├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── Makefile.am ├── Makefile.in ├── NEWS ├── README ├── README.md ├── aclocal.m4 ├── common.c ├── config.h.in ├── configure ├── configure.ac ├── install-sh ├── luvi.h ├── luvi.proto ├── master.c ├── missing ├── run.sh └── slave.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Michael R. Hines 2 | michael@hinespot.com 3 | http://michael.hinespot.com 4 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | ChangeLog: 2 | 3 | (01/1/2013), Version 1.0: 4 | * Working version of parallel master/slave x264 transcoding using ffmpeg libraries 5 | * Bottlenecks seem to be all worked out and packets are properly distributed to all the slaves 6 | * Network throughput between master/slave is within tolerance (around 400-600 megabits/second) 7 | * Audio/Video is copied with correct timestamps, but needs another quick (-c copy) pass through ffmpeg 8 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, 5 | Inc. 6 | 7 | Copying and distribution of this file, with or without modification, 8 | are permitted in any medium without royalty provided the copyright 9 | notice and this notice are preserved. This file is offered as-is, 10 | without warranty of any kind. 11 | 12 | Basic Installation 13 | ================== 14 | 15 | Briefly, the shell commands `./configure; make; make install' should 16 | configure, build, and install this package. The following 17 | more-detailed instructions are generic; see the `README' file for 18 | instructions specific to this package. Some packages provide this 19 | `INSTALL' file but do not implement all of the features documented 20 | below. The lack of an optional feature in a given package is not 21 | necessarily a bug. More recommendations for GNU packages can be found 22 | in *note Makefile Conventions: (standards)Makefile Conventions. 23 | 24 | The `configure' shell script attempts to guess correct values for 25 | various system-dependent variables used during compilation. It uses 26 | those values to create a `Makefile' in each directory of the package. 27 | It may also create one or more `.h' files containing system-dependent 28 | definitions. Finally, it creates a shell script `config.status' that 29 | you can run in the future to recreate the current configuration, and a 30 | file `config.log' containing compiler output (useful mainly for 31 | debugging `configure'). 32 | 33 | It can also use an optional file (typically called `config.cache' 34 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 35 | the results of its tests to speed up reconfiguring. Caching is 36 | disabled by default to prevent problems with accidental use of stale 37 | cache files. 38 | 39 | If you need to do unusual things to compile the package, please try 40 | to figure out how `configure' could check whether to do them, and mail 41 | diffs or instructions to the address given in the `README' so they can 42 | be considered for the next release. If you are using the cache, and at 43 | some point `config.cache' contains results you don't want to keep, you 44 | may remove or edit it. 45 | 46 | The file `configure.ac' (or `configure.in') is used to create 47 | `configure' by a program called `autoconf'. You need `configure.ac' if 48 | you want to change it or regenerate `configure' using a newer version 49 | of `autoconf'. 50 | 51 | The simplest way to compile this package is: 52 | 53 | 1. `cd' to the directory containing the package's source code and type 54 | `./configure' to configure the package for your system. 55 | 56 | Running `configure' might take a while. While running, it prints 57 | some messages telling which features it is checking for. 58 | 59 | 2. Type `make' to compile the package. 60 | 61 | 3. Optionally, type `make check' to run any self-tests that come with 62 | the package, generally using the just-built uninstalled binaries. 63 | 64 | 4. Type `make install' to install the programs and any data files and 65 | documentation. When installing into a prefix owned by root, it is 66 | recommended that the package be configured and built as a regular 67 | user, and only the `make install' phase executed with root 68 | privileges. 69 | 70 | 5. Optionally, type `make installcheck' to repeat any self-tests, but 71 | this time using the binaries in their final installed location. 72 | This target does not install anything. Running this target as a 73 | regular user, particularly if the prior `make install' required 74 | root privileges, verifies that the installation completed 75 | correctly. 76 | 77 | 6. You can remove the program binaries and object files from the 78 | source code directory by typing `make clean'. To also remove the 79 | files that `configure' created (so you can compile the package for 80 | a different kind of computer), type `make distclean'. There is 81 | also a `make maintainer-clean' target, but that is intended mainly 82 | for the package's developers. If you use it, you may have to get 83 | all sorts of other programs in order to regenerate files that came 84 | with the distribution. 85 | 86 | 7. Often, you can also type `make uninstall' to remove the installed 87 | files again. In practice, not all packages have tested that 88 | uninstallation works correctly, even though it is required by the 89 | GNU Coding Standards. 90 | 91 | 8. Some packages, particularly those that use Automake, provide `make 92 | distcheck', which can by used by developers to test that all other 93 | targets like `make install' and `make uninstall' work correctly. 94 | This target is generally not run by end users. 95 | 96 | Compilers and Options 97 | ===================== 98 | 99 | Some systems require unusual options for compilation or linking that 100 | the `configure' script does not know about. Run `./configure --help' 101 | for details on some of the pertinent environment variables. 102 | 103 | You can give `configure' initial values for configuration parameters 104 | by setting variables in the command line or in the environment. Here 105 | is an example: 106 | 107 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 108 | 109 | *Note Defining Variables::, for more details. 110 | 111 | Compiling For Multiple Architectures 112 | ==================================== 113 | 114 | You can compile the package for more than one kind of computer at the 115 | same time, by placing the object files for each architecture in their 116 | own directory. To do this, you can use GNU `make'. `cd' to the 117 | directory where you want the object files and executables to go and run 118 | the `configure' script. `configure' automatically checks for the 119 | source code in the directory that `configure' is in and in `..'. This 120 | is known as a "VPATH" build. 121 | 122 | With a non-GNU `make', it is safer to compile the package for one 123 | architecture at a time in the source code directory. After you have 124 | installed the package for one architecture, use `make distclean' before 125 | reconfiguring for another architecture. 126 | 127 | On MacOS X 10.5 and later systems, you can create libraries and 128 | executables that work on multiple system types--known as "fat" or 129 | "universal" binaries--by specifying multiple `-arch' options to the 130 | compiler but only a single `-arch' option to the preprocessor. Like 131 | this: 132 | 133 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 134 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 135 | CPP="gcc -E" CXXCPP="g++ -E" 136 | 137 | This is not guaranteed to produce working output in all cases, you 138 | may have to build one architecture at a time and combine the results 139 | using the `lipo' tool if you have problems. 140 | 141 | Installation Names 142 | ================== 143 | 144 | By default, `make install' installs the package's commands under 145 | `/usr/local/bin', include files under `/usr/local/include', etc. You 146 | can specify an installation prefix other than `/usr/local' by giving 147 | `configure' the option `--prefix=PREFIX', where PREFIX must be an 148 | absolute file name. 149 | 150 | You can specify separate installation prefixes for 151 | architecture-specific files and architecture-independent files. If you 152 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 153 | PREFIX as the prefix for installing programs and libraries. 154 | Documentation and other data files still use the regular prefix. 155 | 156 | In addition, if you use an unusual directory layout you can give 157 | options like `--bindir=DIR' to specify different values for particular 158 | kinds of files. Run `configure --help' for a list of the directories 159 | you can set and what kinds of files go in them. In general, the 160 | default for these options is expressed in terms of `${prefix}', so that 161 | specifying just `--prefix' will affect all of the other directory 162 | specifications that were not explicitly provided. 163 | 164 | The most portable way to affect installation locations is to pass the 165 | correct locations to `configure'; however, many packages provide one or 166 | both of the following shortcuts of passing variable assignments to the 167 | `make install' command line to change installation locations without 168 | having to reconfigure or recompile. 169 | 170 | The first method involves providing an override variable for each 171 | affected directory. For example, `make install 172 | prefix=/alternate/directory' will choose an alternate location for all 173 | directory configuration variables that were expressed in terms of 174 | `${prefix}'. Any directories that were specified during `configure', 175 | but not in terms of `${prefix}', must each be overridden at install 176 | time for the entire installation to be relocated. The approach of 177 | makefile variable overrides for each directory variable is required by 178 | the GNU Coding Standards, and ideally causes no recompilation. 179 | However, some platforms have known limitations with the semantics of 180 | shared libraries that end up requiring recompilation when using this 181 | method, particularly noticeable in packages that use GNU Libtool. 182 | 183 | The second method involves providing the `DESTDIR' variable. For 184 | example, `make install DESTDIR=/alternate/directory' will prepend 185 | `/alternate/directory' before all installation names. The approach of 186 | `DESTDIR' overrides is not required by the GNU Coding Standards, and 187 | does not work on platforms that have drive letters. On the other hand, 188 | it does better at avoiding recompilation issues, and works well even 189 | when some directory options were not specified in terms of `${prefix}' 190 | at `configure' time. 191 | 192 | Optional Features 193 | ================= 194 | 195 | If the package supports it, you can cause programs to be installed 196 | with an extra prefix or suffix on their names by giving `configure' the 197 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 198 | 199 | Some packages pay attention to `--enable-FEATURE' options to 200 | `configure', where FEATURE indicates an optional part of the package. 201 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 202 | is something like `gnu-as' or `x' (for the X Window System). The 203 | `README' should mention any `--enable-' and `--with-' options that the 204 | package recognizes. 205 | 206 | For packages that use the X Window System, `configure' can usually 207 | find the X include and library files automatically, but if it doesn't, 208 | you can use the `configure' options `--x-includes=DIR' and 209 | `--x-libraries=DIR' to specify their locations. 210 | 211 | Some packages offer the ability to configure how verbose the 212 | execution of `make' will be. For these packages, running `./configure 213 | --enable-silent-rules' sets the default to minimal output, which can be 214 | overridden with `make V=1'; while running `./configure 215 | --disable-silent-rules' sets the default to verbose, which can be 216 | overridden with `make V=0'. 217 | 218 | Particular systems 219 | ================== 220 | 221 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU 222 | CC is not installed, it is recommended to use the following options in 223 | order to use an ANSI C compiler: 224 | 225 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" 226 | 227 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. 228 | 229 | HP-UX `make' updates targets which have the same time stamps as 230 | their prerequisites, which makes it generally unusable when shipped 231 | generated files such as `configure' are involved. Use GNU `make' 232 | instead. 233 | 234 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot 235 | parse its `' header file. The option `-nodtk' can be used as 236 | a workaround. If GNU CC is not installed, it is therefore recommended 237 | to try 238 | 239 | ./configure CC="cc" 240 | 241 | and if that doesn't work, try 242 | 243 | ./configure CC="cc -nodtk" 244 | 245 | On Solaris, don't put `/usr/ucb' early in your `PATH'. This 246 | directory contains several dysfunctional programs; working variants of 247 | these programs are available in `/usr/bin'. So, if you need `/usr/ucb' 248 | in your `PATH', put it _after_ `/usr/bin'. 249 | 250 | On Haiku, software installed for all users goes in `/boot/common', 251 | not `/usr/local'. It is recommended to use the following options: 252 | 253 | ./configure --prefix=/boot/common 254 | 255 | Specifying the System Type 256 | ========================== 257 | 258 | There may be some features `configure' cannot figure out 259 | automatically, but needs to determine by the type of machine the package 260 | will run on. Usually, assuming the package is built to be run on the 261 | _same_ architectures, `configure' can figure that out, but if it prints 262 | a message saying it cannot guess the machine type, give it the 263 | `--build=TYPE' option. TYPE can either be a short name for the system 264 | type, such as `sun4', or a canonical name which has the form: 265 | 266 | CPU-COMPANY-SYSTEM 267 | 268 | where SYSTEM can have one of these forms: 269 | 270 | OS 271 | KERNEL-OS 272 | 273 | See the file `config.sub' for the possible values of each field. If 274 | `config.sub' isn't included in this package, then this package doesn't 275 | need to know the machine type. 276 | 277 | If you are _building_ compiler tools for cross-compiling, you should 278 | use the option `--target=TYPE' to select the type of system they will 279 | produce code for. 280 | 281 | If you want to _use_ a cross compiler, that generates code for a 282 | platform different from the build platform, you should specify the 283 | "host" platform (i.e., that on which the generated programs will 284 | eventually be run) with `--host=TYPE'. 285 | 286 | Sharing Defaults 287 | ================ 288 | 289 | If you want to set default values for `configure' scripts to share, 290 | you can create a site shell script called `config.site' that gives 291 | default values for variables like `CC', `cache_file', and `prefix'. 292 | `configure' looks for `PREFIX/share/config.site' if it exists, then 293 | `PREFIX/etc/config.site' if it exists. Or, you can set the 294 | `CONFIG_SITE' environment variable to the location of the site script. 295 | A warning: not all `configure' scripts look for a site script. 296 | 297 | Defining Variables 298 | ================== 299 | 300 | Variables not defined in a site shell script can be set in the 301 | environment passed to `configure'. However, some packages may run 302 | configure again during the build, and the customized values of these 303 | variables may be lost. In order to avoid this problem, you should set 304 | them in the `configure' command line, using `VAR=value'. For example: 305 | 306 | ./configure CC=/usr/local2/bin/gcc 307 | 308 | causes the specified `gcc' to be used as the C compiler (unless it is 309 | overridden in the site shell script). 310 | 311 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 312 | an Autoconf bug. Until the bug is fixed you can use this workaround: 313 | 314 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 315 | 316 | `configure' Invocation 317 | ====================== 318 | 319 | `configure' recognizes the following options to control how it 320 | operates. 321 | 322 | `--help' 323 | `-h' 324 | Print a summary of all of the options to `configure', and exit. 325 | 326 | `--help=short' 327 | `--help=recursive' 328 | Print a summary of the options unique to this package's 329 | `configure', and exit. The `short' variant lists options used 330 | only in the top level, while the `recursive' variant lists options 331 | also present in any nested packages. 332 | 333 | `--version' 334 | `-V' 335 | Print the version of Autoconf used to generate the `configure' 336 | script, and exit. 337 | 338 | `--cache-file=FILE' 339 | Enable the cache: use and save the results of the tests in FILE, 340 | traditionally `config.cache'. FILE defaults to `/dev/null' to 341 | disable caching. 342 | 343 | `--config-cache' 344 | `-C' 345 | Alias for `--cache-file=config.cache'. 346 | 347 | `--quiet' 348 | `--silent' 349 | `-q' 350 | Do not print messages saying which checks are being made. To 351 | suppress all normal output, redirect it to `/dev/null' (any error 352 | messages will still be shown). 353 | 354 | `--srcdir=DIR' 355 | Look for the package's source code in directory DIR. Usually 356 | `configure' can determine that directory automatically. 357 | 358 | `--prefix=DIR' 359 | Use DIR as the installation prefix. *note Installation Names:: 360 | for more details, including other options available for fine-tuning 361 | the installation locations. 362 | 363 | `--no-create' 364 | `-n' 365 | Run the configure checks, but stop before creating any output 366 | files. 367 | 368 | `configure' also accepts some other, not widely useful, options. Run 369 | `configure --help' for more details. 370 | 371 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | CC = @CC@ 2 | CFLAGS = @CFLAGS@ 3 | INSTALL = @INSTALL@ 4 | INSTALL_PROGRAM= @INSTALL_PROGRAM@ 5 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ 6 | LIBS = @LIBS@ 7 | INCLUDE = @DEFS@ 8 | LDFLAGS = @LDFLAGS@ 9 | PROTOBUFCMD = @PROTOBUF@ 10 | 11 | EXECUTABLES=luvi_master luvi_slave 12 | PROTOSOURCES=luvi.pb-c.c 13 | SOURCES=common.c luvi.h 14 | EXTRA_DIST=$(SOURCES) master.c slave.c luvi.proto 15 | all: $(EXECUTABLES) 16 | 17 | luvi.pb-c.c: luvi.proto 18 | $(PROTOBUFCMD) --c_out=. luvi.proto 19 | 20 | luvi_master: master.c $(SOURCES) $(PROTOSOURCES) 21 | $(CC) -g $(CFLAGS) -o luvi_master master.c $(INCLUDE) $(SOURCES) $(PROTOSOURCES) $(LIBS) $(LDFLAGS) 22 | 23 | luvi_slave: slave.c $(SOURCES) $(PROTOSOURCES) 24 | $(CC) -g $(CFLAGS) -o luvi_slave slave.c $(INCLUDE) $(SOURCES) $(PROTOSOURCES) $(LIBS) $(LDFLAGS) 25 | 26 | clean: 27 | rm -f $(EXECUTABLES) $(PROTOSOURCES) luvi.pb-c.h 28 | 29 | install: 30 | $(INSTALL) -m 0755 luvi_master $(bindir)/luvi_master 31 | $(INSTALL) -m 0755 luvi_slave $(bindir)/luvi_slave 32 | 33 | uninstall: 34 | rm -f $(bindir)/luvi_master 35 | rm -f $(bindir)/luvi_slave 36 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile.in generated by automake 1.11.6 from Makefile.am. 2 | # @configure_input@ 3 | 4 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 5 | # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software 6 | # Foundation, Inc. 7 | # This Makefile.in is free software; the Free Software Foundation 8 | # gives unlimited permission to copy and/or distribute it, 9 | # with or without modifications, as long as this notice is preserved. 10 | 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 13 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 14 | # PARTICULAR PURPOSE. 15 | 16 | @SET_MAKE@ 17 | VPATH = @srcdir@ 18 | am__make_dryrun = \ 19 | { \ 20 | am__dry=no; \ 21 | case $$MAKEFLAGS in \ 22 | *\\[\ \ ]*) \ 23 | echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ 24 | | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ 25 | *) \ 26 | for am__flg in $$MAKEFLAGS; do \ 27 | case $$am__flg in \ 28 | *=*|--*) ;; \ 29 | *n*) am__dry=yes; break;; \ 30 | esac; \ 31 | done;; \ 32 | esac; \ 33 | test $$am__dry = yes; \ 34 | } 35 | pkgdatadir = $(datadir)/@PACKAGE@ 36 | pkgincludedir = $(includedir)/@PACKAGE@ 37 | pkglibdir = $(libdir)/@PACKAGE@ 38 | pkglibexecdir = $(libexecdir)/@PACKAGE@ 39 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 40 | install_sh_DATA = $(install_sh) -c -m 644 41 | install_sh_PROGRAM = $(install_sh) -c 42 | install_sh_SCRIPT = $(install_sh) -c 43 | INSTALL_HEADER = $(INSTALL_DATA) 44 | transform = $(program_transform_name) 45 | NORMAL_INSTALL = : 46 | PRE_INSTALL = : 47 | POST_INSTALL = : 48 | NORMAL_UNINSTALL = : 49 | PRE_UNINSTALL = : 50 | POST_UNINSTALL = : 51 | subdir = . 52 | DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ 53 | $(srcdir)/Makefile.in $(srcdir)/config.h.in \ 54 | $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ 55 | install-sh missing 56 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 57 | am__aclocal_m4_deps = $(top_srcdir)/configure.ac 58 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 59 | $(ACLOCAL_M4) 60 | am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ 61 | configure.lineno config.status.lineno 62 | mkinstalldirs = $(install_sh) -d 63 | CONFIG_HEADER = config.h 64 | CONFIG_CLEAN_FILES = 65 | CONFIG_CLEAN_VPATH_FILES = 66 | DIST_SOURCES = 67 | am__can_run_installinfo = \ 68 | case $$AM_UPDATE_INFO_DIR in \ 69 | n|no|NO) false;; \ 70 | *) (install-info --version) >/dev/null 2>&1;; \ 71 | esac 72 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 73 | distdir = $(PACKAGE)-$(VERSION) 74 | top_distdir = $(distdir) 75 | am__remove_distdir = \ 76 | if test -d "$(distdir)"; then \ 77 | find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ 78 | && rm -rf "$(distdir)" \ 79 | || { sleep 5 && rm -rf "$(distdir)"; }; \ 80 | else :; fi 81 | DIST_ARCHIVES = $(distdir).tar.gz 82 | GZIP_ENV = --best 83 | distuninstallcheck_listfiles = find . -type f -print 84 | am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ 85 | | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' 86 | distcleancheck_listfiles = find . -type f -print 87 | ACLOCAL = @ACLOCAL@ 88 | AMTAR = @AMTAR@ 89 | AUTOCONF = @AUTOCONF@ 90 | AUTOHEADER = @AUTOHEADER@ 91 | AUTOMAKE = @AUTOMAKE@ 92 | AWK = @AWK@ 93 | CC = @CC@ 94 | CCDEPMODE = @CCDEPMODE@ 95 | CFLAGS = @CFLAGS@ 96 | CPP = @CPP@ 97 | CPPFLAGS = @CPPFLAGS@ 98 | CYGPATH_W = @CYGPATH_W@ 99 | DEFS = @DEFS@ 100 | DEPDIR = @DEPDIR@ 101 | ECHO_C = @ECHO_C@ 102 | ECHO_N = @ECHO_N@ 103 | ECHO_T = @ECHO_T@ 104 | EGREP = @EGREP@ 105 | EXEEXT = @EXEEXT@ 106 | GREP = @GREP@ 107 | INSTALL = @INSTALL@ 108 | INSTALL_DATA = @INSTALL_DATA@ 109 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ 110 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ 111 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 112 | LDFLAGS = @LDFLAGS@ 113 | LIBOBJS = @LIBOBJS@ 114 | LIBS = @LIBS@ 115 | LTLIBOBJS = @LTLIBOBJS@ 116 | MAKEINFO = @MAKEINFO@ 117 | MKDIR_P = @MKDIR_P@ 118 | OBJEXT = @OBJEXT@ 119 | PACKAGE = @PACKAGE@ 120 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ 121 | PACKAGE_NAME = @PACKAGE_NAME@ 122 | PACKAGE_STRING = @PACKAGE_STRING@ 123 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ 124 | PACKAGE_URL = @PACKAGE_URL@ 125 | PACKAGE_VERSION = @PACKAGE_VERSION@ 126 | PATH_SEPARATOR = @PATH_SEPARATOR@ 127 | PROTOBUF = @PROTOBUF@ 128 | SET_MAKE = @SET_MAKE@ 129 | SHELL = @SHELL@ 130 | STRIP = @STRIP@ 131 | VERSION = @VERSION@ 132 | abs_builddir = @abs_builddir@ 133 | abs_srcdir = @abs_srcdir@ 134 | abs_top_builddir = @abs_top_builddir@ 135 | abs_top_srcdir = @abs_top_srcdir@ 136 | ac_ct_CC = @ac_ct_CC@ 137 | am__include = @am__include@ 138 | am__leading_dot = @am__leading_dot@ 139 | am__quote = @am__quote@ 140 | am__tar = @am__tar@ 141 | am__untar = @am__untar@ 142 | bindir = @bindir@ 143 | build_alias = @build_alias@ 144 | builddir = @builddir@ 145 | datadir = @datadir@ 146 | datarootdir = @datarootdir@ 147 | docdir = @docdir@ 148 | dvidir = @dvidir@ 149 | exec_prefix = @exec_prefix@ 150 | host_alias = @host_alias@ 151 | htmldir = @htmldir@ 152 | includedir = @includedir@ 153 | infodir = @infodir@ 154 | install_sh = @install_sh@ 155 | libdir = @libdir@ 156 | libexecdir = @libexecdir@ 157 | localedir = @localedir@ 158 | localstatedir = @localstatedir@ 159 | mandir = @mandir@ 160 | mkdir_p = @mkdir_p@ 161 | oldincludedir = @oldincludedir@ 162 | pdfdir = @pdfdir@ 163 | prefix = @prefix@ 164 | program_transform_name = @program_transform_name@ 165 | psdir = @psdir@ 166 | sbindir = @sbindir@ 167 | sharedstatedir = @sharedstatedir@ 168 | srcdir = @srcdir@ 169 | sysconfdir = @sysconfdir@ 170 | target_alias = @target_alias@ 171 | top_build_prefix = @top_build_prefix@ 172 | top_builddir = @top_builddir@ 173 | top_srcdir = @top_srcdir@ 174 | INCLUDE = @DEFS@ 175 | PROTOBUFCMD = @PROTOBUF@ 176 | EXECUTABLES = luvi_master luvi_slave 177 | PROTOSOURCES = luvi.pb-c.c 178 | SOURCES = common.c luvi.h 179 | EXTRA_DIST = $(SOURCES) master.c slave.c luvi.proto 180 | all: config.h 181 | $(MAKE) $(AM_MAKEFLAGS) all-am 182 | 183 | .SUFFIXES: 184 | am--refresh: Makefile 185 | @: 186 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 187 | @for dep in $?; do \ 188 | case '$(am__configure_deps)' in \ 189 | *$$dep*) \ 190 | echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ 191 | $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ 192 | && exit 0; \ 193 | exit 1;; \ 194 | esac; \ 195 | done; \ 196 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ 197 | $(am__cd) $(top_srcdir) && \ 198 | $(AUTOMAKE) --gnu Makefile 199 | .PRECIOUS: Makefile 200 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 201 | @case '$?' in \ 202 | *config.status*) \ 203 | echo ' $(SHELL) ./config.status'; \ 204 | $(SHELL) ./config.status;; \ 205 | *) \ 206 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ 207 | cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ 208 | esac; 209 | 210 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) 211 | $(SHELL) ./config.status --recheck 212 | 213 | $(top_srcdir)/configure: $(am__configure_deps) 214 | $(am__cd) $(srcdir) && $(AUTOCONF) 215 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) 216 | $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) 217 | $(am__aclocal_m4_deps): 218 | 219 | config.h: stamp-h1 220 | @if test ! -f $@; then rm -f stamp-h1; else :; fi 221 | @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi 222 | 223 | stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status 224 | @rm -f stamp-h1 225 | cd $(top_builddir) && $(SHELL) ./config.status config.h 226 | $(srcdir)/config.h.in: $(am__configure_deps) 227 | ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) 228 | rm -f stamp-h1 229 | touch $@ 230 | 231 | distclean-hdr: 232 | -rm -f config.h stamp-h1 233 | tags: TAGS 234 | TAGS: 235 | 236 | ctags: CTAGS 237 | CTAGS: 238 | 239 | 240 | distdir: $(DISTFILES) 241 | $(am__remove_distdir) 242 | test -d "$(distdir)" || mkdir "$(distdir)" 243 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 244 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 245 | list='$(DISTFILES)'; \ 246 | dist_files=`for file in $$list; do echo $$file; done | \ 247 | sed -e "s|^$$srcdirstrip/||;t" \ 248 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ 249 | case $$dist_files in \ 250 | */*) $(MKDIR_P) `echo "$$dist_files" | \ 251 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ 252 | sort -u` ;; \ 253 | esac; \ 254 | for file in $$dist_files; do \ 255 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ 256 | if test -d $$d/$$file; then \ 257 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ 258 | if test -d "$(distdir)/$$file"; then \ 259 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ 260 | fi; \ 261 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ 262 | cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ 263 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ 264 | fi; \ 265 | cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ 266 | else \ 267 | test -f "$(distdir)/$$file" \ 268 | || cp -p $$d/$$file "$(distdir)/$$file" \ 269 | || exit 1; \ 270 | fi; \ 271 | done 272 | -test -n "$(am__skip_mode_fix)" \ 273 | || find "$(distdir)" -type d ! -perm -755 \ 274 | -exec chmod u+rwx,go+rx {} \; -o \ 275 | ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ 276 | ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ 277 | ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ 278 | || chmod -R a+r "$(distdir)" 279 | dist-gzip: distdir 280 | tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz 281 | $(am__remove_distdir) 282 | 283 | dist-bzip2: distdir 284 | tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 285 | $(am__remove_distdir) 286 | 287 | dist-lzip: distdir 288 | tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz 289 | $(am__remove_distdir) 290 | 291 | dist-lzma: distdir 292 | tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma 293 | $(am__remove_distdir) 294 | 295 | dist-xz: distdir 296 | tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz 297 | $(am__remove_distdir) 298 | 299 | dist-tarZ: distdir 300 | tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z 301 | $(am__remove_distdir) 302 | 303 | dist-shar: distdir 304 | shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz 305 | $(am__remove_distdir) 306 | 307 | dist-zip: distdir 308 | -rm -f $(distdir).zip 309 | zip -rq $(distdir).zip $(distdir) 310 | $(am__remove_distdir) 311 | 312 | dist dist-all: distdir 313 | tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz 314 | $(am__remove_distdir) 315 | 316 | # This target untars the dist file and tries a VPATH configuration. Then 317 | # it guarantees that the distribution is self-contained by making another 318 | # tarfile. 319 | distcheck: dist 320 | case '$(DIST_ARCHIVES)' in \ 321 | *.tar.gz*) \ 322 | GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ 323 | *.tar.bz2*) \ 324 | bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ 325 | *.tar.lzma*) \ 326 | lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ 327 | *.tar.lz*) \ 328 | lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ 329 | *.tar.xz*) \ 330 | xz -dc $(distdir).tar.xz | $(am__untar) ;;\ 331 | *.tar.Z*) \ 332 | uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ 333 | *.shar.gz*) \ 334 | GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ 335 | *.zip*) \ 336 | unzip $(distdir).zip ;;\ 337 | esac 338 | chmod -R a-w $(distdir); chmod u+w $(distdir) 339 | mkdir $(distdir)/_build 340 | mkdir $(distdir)/_inst 341 | chmod a-w $(distdir) 342 | test -d $(distdir)/_build || exit 0; \ 343 | dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ 344 | && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ 345 | && am__cwd=`pwd` \ 346 | && $(am__cd) $(distdir)/_build \ 347 | && ../configure --srcdir=.. --prefix="$$dc_install_base" \ 348 | $(AM_DISTCHECK_CONFIGURE_FLAGS) \ 349 | $(DISTCHECK_CONFIGURE_FLAGS) \ 350 | && $(MAKE) $(AM_MAKEFLAGS) \ 351 | && $(MAKE) $(AM_MAKEFLAGS) dvi \ 352 | && $(MAKE) $(AM_MAKEFLAGS) check \ 353 | && $(MAKE) $(AM_MAKEFLAGS) install \ 354 | && $(MAKE) $(AM_MAKEFLAGS) installcheck \ 355 | && $(MAKE) $(AM_MAKEFLAGS) uninstall \ 356 | && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ 357 | distuninstallcheck \ 358 | && chmod -R a-w "$$dc_install_base" \ 359 | && ({ \ 360 | (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ 361 | && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ 362 | && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ 363 | && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ 364 | distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ 365 | } || { rm -rf "$$dc_destdir"; exit 1; }) \ 366 | && rm -rf "$$dc_destdir" \ 367 | && $(MAKE) $(AM_MAKEFLAGS) dist \ 368 | && rm -rf $(DIST_ARCHIVES) \ 369 | && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ 370 | && cd "$$am__cwd" \ 371 | || exit 1 372 | $(am__remove_distdir) 373 | @(echo "$(distdir) archives ready for distribution: "; \ 374 | list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ 375 | sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' 376 | distuninstallcheck: 377 | @test -n '$(distuninstallcheck_dir)' || { \ 378 | echo 'ERROR: trying to run $@ with an empty' \ 379 | '$$(distuninstallcheck_dir)' >&2; \ 380 | exit 1; \ 381 | }; \ 382 | $(am__cd) '$(distuninstallcheck_dir)' || { \ 383 | echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ 384 | exit 1; \ 385 | }; \ 386 | test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ 387 | || { echo "ERROR: files left after uninstall:" ; \ 388 | if test -n "$(DESTDIR)"; then \ 389 | echo " (check DESTDIR support)"; \ 390 | fi ; \ 391 | $(distuninstallcheck_listfiles) ; \ 392 | exit 1; } >&2 393 | distcleancheck: distclean 394 | @if test '$(srcdir)' = . ; then \ 395 | echo "ERROR: distcleancheck can only run from a VPATH build" ; \ 396 | exit 1 ; \ 397 | fi 398 | @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ 399 | || { echo "ERROR: files left in build directory after distclean:" ; \ 400 | $(distcleancheck_listfiles) ; \ 401 | exit 1; } >&2 402 | check-am: all-am 403 | check: check-am 404 | all-am: Makefile config.h 405 | installdirs: 406 | install-exec: install-exec-am 407 | install-data: install-data-am 408 | 409 | install-am: all-am 410 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 411 | 412 | installcheck: installcheck-am 413 | install-strip: 414 | if test -z '$(STRIP)'; then \ 415 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 416 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 417 | install; \ 418 | else \ 419 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 420 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 421 | "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ 422 | fi 423 | mostlyclean-generic: 424 | 425 | clean-generic: 426 | 427 | distclean-generic: 428 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 429 | -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) 430 | 431 | maintainer-clean-generic: 432 | @echo "This command is intended for maintainers to use" 433 | @echo "it deletes files that may require special tools to rebuild." 434 | clean-am: clean-generic mostlyclean-am 435 | 436 | distclean: distclean-am 437 | -rm -f $(am__CONFIG_DISTCLEAN_FILES) 438 | -rm -f Makefile 439 | distclean-am: clean-am distclean-generic distclean-hdr 440 | 441 | dvi: dvi-am 442 | 443 | dvi-am: 444 | 445 | html: html-am 446 | 447 | html-am: 448 | 449 | info: info-am 450 | 451 | info-am: 452 | 453 | install-data-am: 454 | 455 | install-dvi: install-dvi-am 456 | 457 | install-dvi-am: 458 | 459 | install-exec-am: 460 | 461 | install-html: install-html-am 462 | 463 | install-html-am: 464 | 465 | install-info: install-info-am 466 | 467 | install-info-am: 468 | 469 | install-man: 470 | 471 | install-pdf: install-pdf-am 472 | 473 | install-pdf-am: 474 | 475 | install-ps: install-ps-am 476 | 477 | install-ps-am: 478 | 479 | installcheck-am: 480 | 481 | maintainer-clean: maintainer-clean-am 482 | -rm -f $(am__CONFIG_DISTCLEAN_FILES) 483 | -rm -rf $(top_srcdir)/autom4te.cache 484 | -rm -f Makefile 485 | maintainer-clean-am: distclean-am maintainer-clean-generic 486 | 487 | mostlyclean: mostlyclean-am 488 | 489 | mostlyclean-am: mostlyclean-generic 490 | 491 | pdf: pdf-am 492 | 493 | pdf-am: 494 | 495 | ps: ps-am 496 | 497 | ps-am: 498 | 499 | uninstall-am: 500 | 501 | .MAKE: all install-am install-strip 502 | 503 | .PHONY: all all-am am--refresh check check-am clean clean-generic dist \ 504 | dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \ 505 | dist-tarZ dist-xz dist-zip distcheck distclean \ 506 | distclean-generic distclean-hdr distcleancheck distdir \ 507 | distuninstallcheck dvi dvi-am html html-am info info-am \ 508 | install install-am install-data install-data-am install-dvi \ 509 | install-dvi-am install-exec install-exec-am install-html \ 510 | install-html-am install-info install-info-am install-man \ 511 | install-pdf install-pdf-am install-ps install-ps-am \ 512 | install-strip installcheck installcheck-am installdirs \ 513 | maintainer-clean maintainer-clean-generic mostlyclean \ 514 | mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am 515 | 516 | all: $(EXECUTABLES) 517 | 518 | luvi.pb-c.c: luvi.proto 519 | $(PROTOBUFCMD) --c_out=. luvi.proto 520 | 521 | luvi_master: master.c $(SOURCES) $(PROTOSOURCES) 522 | $(CC) -g $(CFLAGS) -o luvi_master master.c $(INCLUDE) $(SOURCES) $(PROTOSOURCES) $(LIBS) $(LDFLAGS) 523 | 524 | luvi_slave: slave.c $(SOURCES) $(PROTOSOURCES) 525 | $(CC) -g $(CFLAGS) -o luvi_slave slave.c $(INCLUDE) $(SOURCES) $(PROTOSOURCES) $(LIBS) $(LDFLAGS) 526 | 527 | clean: 528 | rm -f $(EXECUTABLES) $(PROTOSOURCES) luvi.pb-c.h 529 | 530 | install: 531 | $(INSTALL) -m 0755 luvi_master $(bindir)/luvi_master 532 | $(INSTALL) -m 0755 luvi_slave $(bindir)/luvi_slave 533 | 534 | uninstall: 535 | rm -f $(bindir)/luvi_master 536 | rm -f $(bindir)/luvi_slave 537 | 538 | # Tell versions [3.59,3.63) of GNU make to not export all variables. 539 | # Otherwise a system limit (for SysV at least) may be exceeded. 540 | .NOEXPORT: 541 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | nothing 2 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Luvi: A distributed parallel video transcoder 2 | ============================================= 3 | 4 | This program opens your input movie, streams the frames out to 5 | multiple computers (slaves), transcodes them in parallel, 6 | returns the transcoded frames back to the master computer and 7 | saves the resulting video to a new file. 8 | 9 | Originally, the intent of this program was to take my MythTV 10 | recordings and use the computers in my house in parallel to convert 11 | them them to a high-quality Bluray-compatible format in a much 12 | faster time than a single computer could do. 13 | 14 | DEPENDENCIES: 15 | ============================================= 16 | 17 | A) ffmpeg 1.0 and higher: Compile or install them however you see fit 18 | B) x264: The only codec supported right now for transcoding. 19 | With additional help, this can easily be improved. 20 | C) Protocol Buffers: google's data exchange format for network communication 21 | D) libxdo2: A nice library used to keep the computers from going to sleep 22 | while they video is being farmed out for transcoding. 23 | 24 | 25 | USAGE: 26 | ============================================= 27 | Usage is fairly manual right now.... a GUI would be a logical next step. 28 | 29 | 1. Run the master like this: 30 | $ ./master [ input video filename ] [ output.m2ts ] [ port # to which slaves should connect ] [ 0 | 1 ] 31 | 32 | # The last parameter: 33 | '1' means: transcode in parallel using slaves 34 | '0' means: transcode locally (for debugging purposes) 35 | Example: 36 | 37 | $ ./master input.mpg output.m2ts 1264 1 # start and wait for slaves 38 | 39 | At this point, the master will print: 40 | 41 | Ready for slaves. 42 | Waiting for slaves... 43 | Waiting for slaves... 44 | Waiting for slaves... 45 | 46 | 2. Then, on as many computers as you have, run the slaves, like this: 47 | 48 | $ ./slave [ address/name of master ] [ port # ] 49 | 50 | Example: 51 | 52 | $ ./slave localhost 1264 # connect to master and start working 53 | 54 | 3. If you just want to make sure the encoding *works* first locally 55 | without any parallelism (for example to make sure you have the right 56 | ffmpeg libraries installed): 57 | 58 | Example: 59 | 60 | $ ./master input.mpg output.m2ts 1264 0 # will transcode immediately without slaves 61 | 62 | CONFIGURING: 63 | ============================================= 64 | 65 | Things like x264 bitrates, profiles, presets, GOP sizes, and so forth 66 | are all hard-coded inside "common.c". 67 | 68 | Eventually a configuration system will get written when I have free time. 69 | 70 | Feel free to modify (common.c) the file until that time comes.... 71 | 72 | Patches welcome =) 73 | 74 | HOW IT WORKS: 75 | ====================================== 76 | 77 | Parallelism works by grouping multiple GOPs together (currently almost 1000 frames, 78 | spanning about 45-60 frames/GOP on average from the videos I've tested with) 79 | into "ranges" of GOPs. 80 | 81 | Each "range" of GOPs is assigned to a slave. The range includes a "scene-change" GOP from 82 | the previous range which ensures that encoding is done cleanly between the slaves. This 83 | is done by retaining the last GOP of a range and sending it along to the next slave when 84 | the next slave is chosen. 85 | 86 | Everything happens in a single pass: All the video is transcoded in the same order 87 | that it was read from the original video and written back out to the new video in that same 88 | order. This is done by ordering the transcoded ranges into a FIFO while they are multiplexed 89 | across all the slaves. 90 | 91 | The audio is just copied, right now. It is not transcoded. 92 | 93 | The resulting video is written to an MPEG Transport Stream container. 94 | 95 | BUGS: 96 | ====================================== 97 | No bugs with the video transcoding or synchronization. 98 | 99 | The audio copying is weird: It plays back fine in VLC / Mplayer on my desktop, 100 | but unless I to do the following to get the audio stream to function 101 | properly on a Bluray Disk (tsMuxeR won't accept it): 102 | 103 | By doing the following: 104 | 105 | $ ffmpeg -i output.m2ts -vcodec copy -acodec copy -f mpegts -copyts result.m2ts 106 | 107 | This some how "sanitizes" the copied audio stream in a way that I don't 108 | understand, but makes the audio stream compatible for Bluray. Perhaps someone 109 | could help me track down the problem in my code when I copy the audio packets. 110 | 111 | PATCHES / Reporting Bugs: 112 | ====================================== 113 | If you find a bug *cough* segfault *cough*, 114 | please for god's sake, run GDB first. 115 | 116 | Patches welcome! 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Luvi: A distributed parallel video transcoder [ALPHA, Linux/Unix only currently] 2 | ============================================= 3 | 4 | This program opens your input movie, streams the frames out to 5 | multiple computers (slaves), transcodes them in parallel, 6 | returns the transcoded frames back to the master computer and 7 | saves the resulting video to a new file. 8 | 9 | This is alpha code. It currently has only been tested on Ubuntu. 10 | 11 | Dependencies listed below. 12 | 13 | Originally, the intent of this program was to take my MythTV 14 | recordings and use the computers in my house in parallel to convert 15 | them them to a high-quality Bluray-compatible format in a much 16 | faster time than a single computer could do. 17 | 18 | DEPENDENCIES: 19 | ============================================= 20 | 21 | A) ffmpeg 1.0 and higher: Compile or install them however you see fit 22 | B) x264: The only codec supported right now for transcoding. With additional help, this can easily be improved. 23 | C) Protocol Buffers: google's data exchange format for network communication 24 | D) libxdo2: A nice library used to keep the computers from going to sleep 25 | while they video is being farmed out for transcoding. 26 | 27 | USAGE: 28 | ============================================= 29 | Usage is fairly manual right now.... a GUI would be a logical next step. 30 | 31 | 1. Run the master like this: 32 | 33 | $ ./master [ input video filename ] [ output.mkv ] [ port # to which slaves should connect ] [ 0 | 1 ] 34 | 35 | The last parameter: 36 | '1' means: transcode in parallel using slaves 37 | '0' means: transcode locally (for debugging purposes) 38 | Example: 39 | 40 | $ ./master input.mpg output.mkv 1264 1 # start and wait for slaves 41 | 42 | At this point, the master will print: 43 | 44 | Ready for slaves. 45 | 46 | Waiting for slaves... 47 | 48 | Waiting for slaves... 49 | 50 | Waiting for slaves... 51 | 52 | 2. Then, on as many computers as you have, run the slaves, like this: 53 | 54 | $ ./slave [ address/name of master ] [ port # ] 55 | 56 | Example: 57 | 58 | $ ./slave localhost 1264 # connect to master and start working 59 | 60 | 3. If you just want to make sure the encoding *works* first locally 61 | without any parallelism (for example to make sure you have the right 62 | ffmpeg libraries installed): 63 | 64 | Example: 65 | 66 | $ ./master input.mpg output.mkv 1264 0 # will transcode immediately without slaves 67 | 68 | CONFIGURING: 69 | ============================================= 70 | 71 | Things like x264 bitrates, profiles, presets, GOP sizes, and so forth 72 | are all hard-coded inside "common.c". 73 | 74 | Eventually a configuration system will get written when I have free time. 75 | 76 | Feel free to modify (common.c) the file until that time comes.... 77 | 78 | Patches welcome =) 79 | 80 | HOW IT WORKS: 81 | ====================================== 82 | 83 | Parallelism works by grouping multiple GOPs together (currently almost 1000 frames, 84 | spanning about 45-60 frames/GOP on average from the videos I've tested with) 85 | into "ranges" of GOPs. 86 | 87 | Each "range" of GOPs is assigned to a slave. The range includes a "scene-change" GOP from 88 | the previous range which ensures that encoding is done cleanly between the slaves. This 89 | is done by retaining the last GOP of a range and sending it along to the next slave when 90 | the next slave is chosen. 91 | 92 | Everything happens in a single pass: All the video is transcoded in the same order 93 | that it was read from the original video and written back out to the new video in that same 94 | order. This is done by ordering the transcoded ranges into a FIFO while they are multiplexed 95 | across all the slaves. 96 | 97 | The audio is just copied, right now. It is not transcoded. 98 | 99 | The resulting video is written to a Matroska container, but that can easily be changed inside the source code. (Clearly additional command line parameters are necessary). 100 | 101 | BUGS: 102 | ====================================== 103 | No bugs with the video transcoding or synchronization. 104 | 105 | The audio copying is weird: It plays back fine in VLC / Mplayer on my desktop, 106 | but unless I to do the following to get the audio stream to function 107 | properly on a Bluray Disk (tsMuxeR won't accept it): 108 | 109 | By doing the following: 110 | 111 | $ ffmpeg -i output.mkv -vcodec copy -acodec copy -f matroska -copyts result.mkv 112 | 113 | This some how "sanitizes" the copied audio stream in a way that I don't 114 | understand, but makes the audio stream compatible for Bluray. Perhaps someone 115 | could help me track down the problem in my code when I copy the audio packets. 116 | 117 | PATCHES / Reporting Bugs: 118 | ====================================== 119 | If you find a bug *cough* segfault *cough*, 120 | please for god's sake, run GDB first. 121 | 122 | Patches welcome! 123 | -------------------------------------------------------------------------------- /aclocal.m4: -------------------------------------------------------------------------------- 1 | # generated automatically by aclocal 1.11.6 -*- Autoconf -*- 2 | 3 | # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 4 | # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, 5 | # Inc. 6 | # This file is free software; the Free Software Foundation 7 | # gives unlimited permission to copy and/or distribute it, 8 | # with or without modifications, as long as this notice is preserved. 9 | 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 12 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. 14 | 15 | m4_ifndef([AC_AUTOCONF_VERSION], 16 | [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl 17 | m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, 18 | [m4_warning([this file was generated for autoconf 2.69. 19 | You have another version of autoconf. It may work, but is not guaranteed to. 20 | If you have problems, you may need to regenerate the build system entirely. 21 | To do so, use the procedure documented by the package, typically `autoreconf'.])]) 22 | 23 | # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software 24 | # Foundation, Inc. 25 | # 26 | # This file is free software; the Free Software Foundation 27 | # gives unlimited permission to copy and/or distribute it, 28 | # with or without modifications, as long as this notice is preserved. 29 | 30 | # serial 1 31 | 32 | # AM_AUTOMAKE_VERSION(VERSION) 33 | # ---------------------------- 34 | # Automake X.Y traces this macro to ensure aclocal.m4 has been 35 | # generated from the m4 files accompanying Automake X.Y. 36 | # (This private macro should not be called outside this file.) 37 | AC_DEFUN([AM_AUTOMAKE_VERSION], 38 | [am__api_version='1.11' 39 | dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to 40 | dnl require some minimum version. Point them to the right macro. 41 | m4_if([$1], [1.11.6], [], 42 | [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl 43 | ]) 44 | 45 | # _AM_AUTOCONF_VERSION(VERSION) 46 | # ----------------------------- 47 | # aclocal traces this macro to find the Autoconf version. 48 | # This is a private macro too. Using m4_define simplifies 49 | # the logic in aclocal, which can simply ignore this definition. 50 | m4_define([_AM_AUTOCONF_VERSION], []) 51 | 52 | # AM_SET_CURRENT_AUTOMAKE_VERSION 53 | # ------------------------------- 54 | # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. 55 | # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. 56 | AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], 57 | [AM_AUTOMAKE_VERSION([1.11.6])dnl 58 | m4_ifndef([AC_AUTOCONF_VERSION], 59 | [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl 60 | _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) 61 | 62 | # AM_AUX_DIR_EXPAND -*- Autoconf -*- 63 | 64 | # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. 65 | # 66 | # This file is free software; the Free Software Foundation 67 | # gives unlimited permission to copy and/or distribute it, 68 | # with or without modifications, as long as this notice is preserved. 69 | 70 | # serial 1 71 | 72 | # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets 73 | # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to 74 | # `$srcdir', `$srcdir/..', or `$srcdir/../..'. 75 | # 76 | # Of course, Automake must honor this variable whenever it calls a 77 | # tool from the auxiliary directory. The problem is that $srcdir (and 78 | # therefore $ac_aux_dir as well) can be either absolute or relative, 79 | # depending on how configure is run. This is pretty annoying, since 80 | # it makes $ac_aux_dir quite unusable in subdirectories: in the top 81 | # source directory, any form will work fine, but in subdirectories a 82 | # relative path needs to be adjusted first. 83 | # 84 | # $ac_aux_dir/missing 85 | # fails when called from a subdirectory if $ac_aux_dir is relative 86 | # $top_srcdir/$ac_aux_dir/missing 87 | # fails if $ac_aux_dir is absolute, 88 | # fails when called from a subdirectory in a VPATH build with 89 | # a relative $ac_aux_dir 90 | # 91 | # The reason of the latter failure is that $top_srcdir and $ac_aux_dir 92 | # are both prefixed by $srcdir. In an in-source build this is usually 93 | # harmless because $srcdir is `.', but things will broke when you 94 | # start a VPATH build or use an absolute $srcdir. 95 | # 96 | # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, 97 | # iff we strip the leading $srcdir from $ac_aux_dir. That would be: 98 | # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` 99 | # and then we would define $MISSING as 100 | # MISSING="\${SHELL} $am_aux_dir/missing" 101 | # This will work as long as MISSING is not called from configure, because 102 | # unfortunately $(top_srcdir) has no meaning in configure. 103 | # However there are other variables, like CC, which are often used in 104 | # configure, and could therefore not use this "fixed" $ac_aux_dir. 105 | # 106 | # Another solution, used here, is to always expand $ac_aux_dir to an 107 | # absolute PATH. The drawback is that using absolute paths prevent a 108 | # configured tree to be moved without reconfiguration. 109 | 110 | AC_DEFUN([AM_AUX_DIR_EXPAND], 111 | [dnl Rely on autoconf to set up CDPATH properly. 112 | AC_PREREQ([2.50])dnl 113 | # expand $ac_aux_dir to an absolute path 114 | am_aux_dir=`cd $ac_aux_dir && pwd` 115 | ]) 116 | 117 | # AM_CONDITIONAL -*- Autoconf -*- 118 | 119 | # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 120 | # Free Software Foundation, Inc. 121 | # 122 | # This file is free software; the Free Software Foundation 123 | # gives unlimited permission to copy and/or distribute it, 124 | # with or without modifications, as long as this notice is preserved. 125 | 126 | # serial 9 127 | 128 | # AM_CONDITIONAL(NAME, SHELL-CONDITION) 129 | # ------------------------------------- 130 | # Define a conditional. 131 | AC_DEFUN([AM_CONDITIONAL], 132 | [AC_PREREQ(2.52)dnl 133 | ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], 134 | [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl 135 | AC_SUBST([$1_TRUE])dnl 136 | AC_SUBST([$1_FALSE])dnl 137 | _AM_SUBST_NOTMAKE([$1_TRUE])dnl 138 | _AM_SUBST_NOTMAKE([$1_FALSE])dnl 139 | m4_define([_AM_COND_VALUE_$1], [$2])dnl 140 | if $2; then 141 | $1_TRUE= 142 | $1_FALSE='#' 143 | else 144 | $1_TRUE='#' 145 | $1_FALSE= 146 | fi 147 | AC_CONFIG_COMMANDS_PRE( 148 | [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then 149 | AC_MSG_ERROR([[conditional "$1" was never defined. 150 | Usually this means the macro was only invoked conditionally.]]) 151 | fi])]) 152 | 153 | # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, 154 | # 2010, 2011 Free Software Foundation, Inc. 155 | # 156 | # This file is free software; the Free Software Foundation 157 | # gives unlimited permission to copy and/or distribute it, 158 | # with or without modifications, as long as this notice is preserved. 159 | 160 | # serial 12 161 | 162 | # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be 163 | # written in clear, in which case automake, when reading aclocal.m4, 164 | # will think it sees a *use*, and therefore will trigger all it's 165 | # C support machinery. Also note that it means that autoscan, seeing 166 | # CC etc. in the Makefile, will ask for an AC_PROG_CC use... 167 | 168 | 169 | # _AM_DEPENDENCIES(NAME) 170 | # ---------------------- 171 | # See how the compiler implements dependency checking. 172 | # NAME is "CC", "CXX", "GCJ", or "OBJC". 173 | # We try a few techniques and use that to set a single cache variable. 174 | # 175 | # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was 176 | # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular 177 | # dependency, and given that the user is not expected to run this macro, 178 | # just rely on AC_PROG_CC. 179 | AC_DEFUN([_AM_DEPENDENCIES], 180 | [AC_REQUIRE([AM_SET_DEPDIR])dnl 181 | AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl 182 | AC_REQUIRE([AM_MAKE_INCLUDE])dnl 183 | AC_REQUIRE([AM_DEP_TRACK])dnl 184 | 185 | ifelse([$1], CC, [depcc="$CC" am_compiler_list=], 186 | [$1], CXX, [depcc="$CXX" am_compiler_list=], 187 | [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], 188 | [$1], UPC, [depcc="$UPC" am_compiler_list=], 189 | [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], 190 | [depcc="$$1" am_compiler_list=]) 191 | 192 | AC_CACHE_CHECK([dependency style of $depcc], 193 | [am_cv_$1_dependencies_compiler_type], 194 | [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then 195 | # We make a subdir and do the tests there. Otherwise we can end up 196 | # making bogus files that we don't know about and never remove. For 197 | # instance it was reported that on HP-UX the gcc test will end up 198 | # making a dummy file named `D' -- because `-MD' means `put the output 199 | # in D'. 200 | rm -rf conftest.dir 201 | mkdir conftest.dir 202 | # Copy depcomp to subdir because otherwise we won't find it if we're 203 | # using a relative directory. 204 | cp "$am_depcomp" conftest.dir 205 | cd conftest.dir 206 | # We will build objects and dependencies in a subdirectory because 207 | # it helps to detect inapplicable dependency modes. For instance 208 | # both Tru64's cc and ICC support -MD to output dependencies as a 209 | # side effect of compilation, but ICC will put the dependencies in 210 | # the current directory while Tru64 will put them in the object 211 | # directory. 212 | mkdir sub 213 | 214 | am_cv_$1_dependencies_compiler_type=none 215 | if test "$am_compiler_list" = ""; then 216 | am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` 217 | fi 218 | am__universal=false 219 | m4_case([$1], [CC], 220 | [case " $depcc " in #( 221 | *\ -arch\ *\ -arch\ *) am__universal=true ;; 222 | esac], 223 | [CXX], 224 | [case " $depcc " in #( 225 | *\ -arch\ *\ -arch\ *) am__universal=true ;; 226 | esac]) 227 | 228 | for depmode in $am_compiler_list; do 229 | # Setup a source with many dependencies, because some compilers 230 | # like to wrap large dependency lists on column 80 (with \), and 231 | # we should not choose a depcomp mode which is confused by this. 232 | # 233 | # We need to recreate these files for each test, as the compiler may 234 | # overwrite some of them when testing with obscure command lines. 235 | # This happens at least with the AIX C compiler. 236 | : > sub/conftest.c 237 | for i in 1 2 3 4 5 6; do 238 | echo '#include "conftst'$i'.h"' >> sub/conftest.c 239 | # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with 240 | # Solaris 8's {/usr,}/bin/sh. 241 | touch sub/conftst$i.h 242 | done 243 | echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf 244 | 245 | # We check with `-c' and `-o' for the sake of the "dashmstdout" 246 | # mode. It turns out that the SunPro C++ compiler does not properly 247 | # handle `-M -o', and we need to detect this. Also, some Intel 248 | # versions had trouble with output in subdirs 249 | am__obj=sub/conftest.${OBJEXT-o} 250 | am__minus_obj="-o $am__obj" 251 | case $depmode in 252 | gcc) 253 | # This depmode causes a compiler race in universal mode. 254 | test "$am__universal" = false || continue 255 | ;; 256 | nosideeffect) 257 | # after this tag, mechanisms are not by side-effect, so they'll 258 | # only be used when explicitly requested 259 | if test "x$enable_dependency_tracking" = xyes; then 260 | continue 261 | else 262 | break 263 | fi 264 | ;; 265 | msvc7 | msvc7msys | msvisualcpp | msvcmsys) 266 | # This compiler won't grok `-c -o', but also, the minuso test has 267 | # not run yet. These depmodes are late enough in the game, and 268 | # so weak that their functioning should not be impacted. 269 | am__obj=conftest.${OBJEXT-o} 270 | am__minus_obj= 271 | ;; 272 | none) break ;; 273 | esac 274 | if depmode=$depmode \ 275 | source=sub/conftest.c object=$am__obj \ 276 | depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ 277 | $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ 278 | >/dev/null 2>conftest.err && 279 | grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && 280 | grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && 281 | grep $am__obj sub/conftest.Po > /dev/null 2>&1 && 282 | ${MAKE-make} -s -f confmf > /dev/null 2>&1; then 283 | # icc doesn't choke on unknown options, it will just issue warnings 284 | # or remarks (even with -Werror). So we grep stderr for any message 285 | # that says an option was ignored or not supported. 286 | # When given -MP, icc 7.0 and 7.1 complain thusly: 287 | # icc: Command line warning: ignoring option '-M'; no argument required 288 | # The diagnosis changed in icc 8.0: 289 | # icc: Command line remark: option '-MP' not supported 290 | if (grep 'ignoring option' conftest.err || 291 | grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else 292 | am_cv_$1_dependencies_compiler_type=$depmode 293 | break 294 | fi 295 | fi 296 | done 297 | 298 | cd .. 299 | rm -rf conftest.dir 300 | else 301 | am_cv_$1_dependencies_compiler_type=none 302 | fi 303 | ]) 304 | AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) 305 | AM_CONDITIONAL([am__fastdep$1], [ 306 | test "x$enable_dependency_tracking" != xno \ 307 | && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) 308 | ]) 309 | 310 | 311 | # AM_SET_DEPDIR 312 | # ------------- 313 | # Choose a directory name for dependency files. 314 | # This macro is AC_REQUIREd in _AM_DEPENDENCIES 315 | AC_DEFUN([AM_SET_DEPDIR], 316 | [AC_REQUIRE([AM_SET_LEADING_DOT])dnl 317 | AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl 318 | ]) 319 | 320 | 321 | # AM_DEP_TRACK 322 | # ------------ 323 | AC_DEFUN([AM_DEP_TRACK], 324 | [AC_ARG_ENABLE(dependency-tracking, 325 | [ --disable-dependency-tracking speeds up one-time build 326 | --enable-dependency-tracking do not reject slow dependency extractors]) 327 | if test "x$enable_dependency_tracking" != xno; then 328 | am_depcomp="$ac_aux_dir/depcomp" 329 | AMDEPBACKSLASH='\' 330 | am__nodep='_no' 331 | fi 332 | AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) 333 | AC_SUBST([AMDEPBACKSLASH])dnl 334 | _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl 335 | AC_SUBST([am__nodep])dnl 336 | _AM_SUBST_NOTMAKE([am__nodep])dnl 337 | ]) 338 | 339 | # Generate code to set up dependency tracking. -*- Autoconf -*- 340 | 341 | # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 342 | # Free Software Foundation, Inc. 343 | # 344 | # This file is free software; the Free Software Foundation 345 | # gives unlimited permission to copy and/or distribute it, 346 | # with or without modifications, as long as this notice is preserved. 347 | 348 | #serial 5 349 | 350 | # _AM_OUTPUT_DEPENDENCY_COMMANDS 351 | # ------------------------------ 352 | AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], 353 | [{ 354 | # Autoconf 2.62 quotes --file arguments for eval, but not when files 355 | # are listed without --file. Let's play safe and only enable the eval 356 | # if we detect the quoting. 357 | case $CONFIG_FILES in 358 | *\'*) eval set x "$CONFIG_FILES" ;; 359 | *) set x $CONFIG_FILES ;; 360 | esac 361 | shift 362 | for mf 363 | do 364 | # Strip MF so we end up with the name of the file. 365 | mf=`echo "$mf" | sed -e 's/:.*$//'` 366 | # Check whether this is an Automake generated Makefile or not. 367 | # We used to match only the files named `Makefile.in', but 368 | # some people rename them; so instead we look at the file content. 369 | # Grep'ing the first line is not enough: some people post-process 370 | # each Makefile.in and add a new line on top of each file to say so. 371 | # Grep'ing the whole file is not good either: AIX grep has a line 372 | # limit of 2048, but all sed's we know have understand at least 4000. 373 | if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then 374 | dirpart=`AS_DIRNAME("$mf")` 375 | else 376 | continue 377 | fi 378 | # Extract the definition of DEPDIR, am__include, and am__quote 379 | # from the Makefile without running `make'. 380 | DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` 381 | test -z "$DEPDIR" && continue 382 | am__include=`sed -n 's/^am__include = //p' < "$mf"` 383 | test -z "am__include" && continue 384 | am__quote=`sed -n 's/^am__quote = //p' < "$mf"` 385 | # When using ansi2knr, U may be empty or an underscore; expand it 386 | U=`sed -n 's/^U = //p' < "$mf"` 387 | # Find all dependency output files, they are included files with 388 | # $(DEPDIR) in their names. We invoke sed twice because it is the 389 | # simplest approach to changing $(DEPDIR) to its actual value in the 390 | # expansion. 391 | for file in `sed -n " 392 | s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ 393 | sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do 394 | # Make sure the directory exists. 395 | test -f "$dirpart/$file" && continue 396 | fdir=`AS_DIRNAME(["$file"])` 397 | AS_MKDIR_P([$dirpart/$fdir]) 398 | # echo "creating $dirpart/$file" 399 | echo '# dummy' > "$dirpart/$file" 400 | done 401 | done 402 | } 403 | ])# _AM_OUTPUT_DEPENDENCY_COMMANDS 404 | 405 | 406 | # AM_OUTPUT_DEPENDENCY_COMMANDS 407 | # ----------------------------- 408 | # This macro should only be invoked once -- use via AC_REQUIRE. 409 | # 410 | # This code is only required when automatic dependency tracking 411 | # is enabled. FIXME. This creates each `.P' file that we will 412 | # need in order to bootstrap the dependency handling code. 413 | AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], 414 | [AC_CONFIG_COMMANDS([depfiles], 415 | [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], 416 | [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) 417 | ]) 418 | 419 | # Do all the work for Automake. -*- Autoconf -*- 420 | 421 | # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 422 | # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. 423 | # 424 | # This file is free software; the Free Software Foundation 425 | # gives unlimited permission to copy and/or distribute it, 426 | # with or without modifications, as long as this notice is preserved. 427 | 428 | # serial 16 429 | 430 | # This macro actually does too much. Some checks are only needed if 431 | # your package does certain things. But this isn't really a big deal. 432 | 433 | # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) 434 | # AM_INIT_AUTOMAKE([OPTIONS]) 435 | # ----------------------------------------------- 436 | # The call with PACKAGE and VERSION arguments is the old style 437 | # call (pre autoconf-2.50), which is being phased out. PACKAGE 438 | # and VERSION should now be passed to AC_INIT and removed from 439 | # the call to AM_INIT_AUTOMAKE. 440 | # We support both call styles for the transition. After 441 | # the next Automake release, Autoconf can make the AC_INIT 442 | # arguments mandatory, and then we can depend on a new Autoconf 443 | # release and drop the old call support. 444 | AC_DEFUN([AM_INIT_AUTOMAKE], 445 | [AC_PREREQ([2.62])dnl 446 | dnl Autoconf wants to disallow AM_ names. We explicitly allow 447 | dnl the ones we care about. 448 | m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl 449 | AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl 450 | AC_REQUIRE([AC_PROG_INSTALL])dnl 451 | if test "`cd $srcdir && pwd`" != "`pwd`"; then 452 | # Use -I$(srcdir) only when $(srcdir) != ., so that make's output 453 | # is not polluted with repeated "-I." 454 | AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl 455 | # test to see if srcdir already configured 456 | if test -f $srcdir/config.status; then 457 | AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) 458 | fi 459 | fi 460 | 461 | # test whether we have cygpath 462 | if test -z "$CYGPATH_W"; then 463 | if (cygpath --version) >/dev/null 2>/dev/null; then 464 | CYGPATH_W='cygpath -w' 465 | else 466 | CYGPATH_W=echo 467 | fi 468 | fi 469 | AC_SUBST([CYGPATH_W]) 470 | 471 | # Define the identity of the package. 472 | dnl Distinguish between old-style and new-style calls. 473 | m4_ifval([$2], 474 | [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl 475 | AC_SUBST([PACKAGE], [$1])dnl 476 | AC_SUBST([VERSION], [$2])], 477 | [_AM_SET_OPTIONS([$1])dnl 478 | dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. 479 | m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, 480 | [m4_fatal([AC_INIT should be called with package and version arguments])])dnl 481 | AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl 482 | AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl 483 | 484 | _AM_IF_OPTION([no-define],, 485 | [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) 486 | AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl 487 | 488 | # Some tools Automake needs. 489 | AC_REQUIRE([AM_SANITY_CHECK])dnl 490 | AC_REQUIRE([AC_ARG_PROGRAM])dnl 491 | AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) 492 | AM_MISSING_PROG(AUTOCONF, autoconf) 493 | AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) 494 | AM_MISSING_PROG(AUTOHEADER, autoheader) 495 | AM_MISSING_PROG(MAKEINFO, makeinfo) 496 | AC_REQUIRE([AM_PROG_INSTALL_SH])dnl 497 | AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl 498 | AC_REQUIRE([AM_PROG_MKDIR_P])dnl 499 | # We need awk for the "check" target. The system "awk" is bad on 500 | # some platforms. 501 | AC_REQUIRE([AC_PROG_AWK])dnl 502 | AC_REQUIRE([AC_PROG_MAKE_SET])dnl 503 | AC_REQUIRE([AM_SET_LEADING_DOT])dnl 504 | _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], 505 | [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], 506 | [_AM_PROG_TAR([v7])])]) 507 | _AM_IF_OPTION([no-dependencies],, 508 | [AC_PROVIDE_IFELSE([AC_PROG_CC], 509 | [_AM_DEPENDENCIES(CC)], 510 | [define([AC_PROG_CC], 511 | defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl 512 | AC_PROVIDE_IFELSE([AC_PROG_CXX], 513 | [_AM_DEPENDENCIES(CXX)], 514 | [define([AC_PROG_CXX], 515 | defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl 516 | AC_PROVIDE_IFELSE([AC_PROG_OBJC], 517 | [_AM_DEPENDENCIES(OBJC)], 518 | [define([AC_PROG_OBJC], 519 | defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl 520 | ]) 521 | _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl 522 | dnl The `parallel-tests' driver may need to know about EXEEXT, so add the 523 | dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro 524 | dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. 525 | AC_CONFIG_COMMANDS_PRE(dnl 526 | [m4_provide_if([_AM_COMPILER_EXEEXT], 527 | [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl 528 | ]) 529 | 530 | dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not 531 | dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further 532 | dnl mangled by Autoconf and run in a shell conditional statement. 533 | m4_define([_AC_COMPILER_EXEEXT], 534 | m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) 535 | 536 | 537 | # When config.status generates a header, we must update the stamp-h file. 538 | # This file resides in the same directory as the config header 539 | # that is generated. The stamp files are numbered to have different names. 540 | 541 | # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the 542 | # loop where config.status creates the headers, so we can generate 543 | # our stamp files there. 544 | AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], 545 | [# Compute $1's index in $config_headers. 546 | _am_arg=$1 547 | _am_stamp_count=1 548 | for _am_header in $config_headers :; do 549 | case $_am_header in 550 | $_am_arg | $_am_arg:* ) 551 | break ;; 552 | * ) 553 | _am_stamp_count=`expr $_am_stamp_count + 1` ;; 554 | esac 555 | done 556 | echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) 557 | 558 | # Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, 559 | # Inc. 560 | # 561 | # This file is free software; the Free Software Foundation 562 | # gives unlimited permission to copy and/or distribute it, 563 | # with or without modifications, as long as this notice is preserved. 564 | 565 | # serial 1 566 | 567 | # AM_PROG_INSTALL_SH 568 | # ------------------ 569 | # Define $install_sh. 570 | AC_DEFUN([AM_PROG_INSTALL_SH], 571 | [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl 572 | if test x"${install_sh}" != xset; then 573 | case $am_aux_dir in 574 | *\ * | *\ *) 575 | install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; 576 | *) 577 | install_sh="\${SHELL} $am_aux_dir/install-sh" 578 | esac 579 | fi 580 | AC_SUBST(install_sh)]) 581 | 582 | # Copyright (C) 2003, 2005 Free Software Foundation, Inc. 583 | # 584 | # This file is free software; the Free Software Foundation 585 | # gives unlimited permission to copy and/or distribute it, 586 | # with or without modifications, as long as this notice is preserved. 587 | 588 | # serial 2 589 | 590 | # Check whether the underlying file-system supports filenames 591 | # with a leading dot. For instance MS-DOS doesn't. 592 | AC_DEFUN([AM_SET_LEADING_DOT], 593 | [rm -rf .tst 2>/dev/null 594 | mkdir .tst 2>/dev/null 595 | if test -d .tst; then 596 | am__leading_dot=. 597 | else 598 | am__leading_dot=_ 599 | fi 600 | rmdir .tst 2>/dev/null 601 | AC_SUBST([am__leading_dot])]) 602 | 603 | # Check to see how 'make' treats includes. -*- Autoconf -*- 604 | 605 | # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. 606 | # 607 | # This file is free software; the Free Software Foundation 608 | # gives unlimited permission to copy and/or distribute it, 609 | # with or without modifications, as long as this notice is preserved. 610 | 611 | # serial 4 612 | 613 | # AM_MAKE_INCLUDE() 614 | # ----------------- 615 | # Check to see how make treats includes. 616 | AC_DEFUN([AM_MAKE_INCLUDE], 617 | [am_make=${MAKE-make} 618 | cat > confinc << 'END' 619 | am__doit: 620 | @echo this is the am__doit target 621 | .PHONY: am__doit 622 | END 623 | # If we don't find an include directive, just comment out the code. 624 | AC_MSG_CHECKING([for style of include used by $am_make]) 625 | am__include="#" 626 | am__quote= 627 | _am_result=none 628 | # First try GNU make style include. 629 | echo "include confinc" > confmf 630 | # Ignore all kinds of additional output from `make'. 631 | case `$am_make -s -f confmf 2> /dev/null` in #( 632 | *the\ am__doit\ target*) 633 | am__include=include 634 | am__quote= 635 | _am_result=GNU 636 | ;; 637 | esac 638 | # Now try BSD make style include. 639 | if test "$am__include" = "#"; then 640 | echo '.include "confinc"' > confmf 641 | case `$am_make -s -f confmf 2> /dev/null` in #( 642 | *the\ am__doit\ target*) 643 | am__include=.include 644 | am__quote="\"" 645 | _am_result=BSD 646 | ;; 647 | esac 648 | fi 649 | AC_SUBST([am__include]) 650 | AC_SUBST([am__quote]) 651 | AC_MSG_RESULT([$_am_result]) 652 | rm -f confinc confmf 653 | ]) 654 | 655 | # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- 656 | 657 | # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 658 | # Free Software Foundation, Inc. 659 | # 660 | # This file is free software; the Free Software Foundation 661 | # gives unlimited permission to copy and/or distribute it, 662 | # with or without modifications, as long as this notice is preserved. 663 | 664 | # serial 6 665 | 666 | # AM_MISSING_PROG(NAME, PROGRAM) 667 | # ------------------------------ 668 | AC_DEFUN([AM_MISSING_PROG], 669 | [AC_REQUIRE([AM_MISSING_HAS_RUN]) 670 | $1=${$1-"${am_missing_run}$2"} 671 | AC_SUBST($1)]) 672 | 673 | 674 | # AM_MISSING_HAS_RUN 675 | # ------------------ 676 | # Define MISSING if not defined so far and test if it supports --run. 677 | # If it does, set am_missing_run to use it, otherwise, to nothing. 678 | AC_DEFUN([AM_MISSING_HAS_RUN], 679 | [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl 680 | AC_REQUIRE_AUX_FILE([missing])dnl 681 | if test x"${MISSING+set}" != xset; then 682 | case $am_aux_dir in 683 | *\ * | *\ *) 684 | MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; 685 | *) 686 | MISSING="\${SHELL} $am_aux_dir/missing" ;; 687 | esac 688 | fi 689 | # Use eval to expand $SHELL 690 | if eval "$MISSING --run true"; then 691 | am_missing_run="$MISSING --run " 692 | else 693 | am_missing_run= 694 | AC_MSG_WARN([`missing' script is too old or missing]) 695 | fi 696 | ]) 697 | 698 | # Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, 699 | # Inc. 700 | # 701 | # This file is free software; the Free Software Foundation 702 | # gives unlimited permission to copy and/or distribute it, 703 | # with or without modifications, as long as this notice is preserved. 704 | 705 | # serial 1 706 | 707 | # AM_PROG_MKDIR_P 708 | # --------------- 709 | # Check for `mkdir -p'. 710 | AC_DEFUN([AM_PROG_MKDIR_P], 711 | [AC_PREREQ([2.60])dnl 712 | AC_REQUIRE([AC_PROG_MKDIR_P])dnl 713 | dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, 714 | dnl while keeping a definition of mkdir_p for backward compatibility. 715 | dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. 716 | dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of 717 | dnl Makefile.ins that do not define MKDIR_P, so we do our own 718 | dnl adjustment using top_builddir (which is defined more often than 719 | dnl MKDIR_P). 720 | AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl 721 | case $mkdir_p in 722 | [[\\/$]]* | ?:[[\\/]]*) ;; 723 | */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; 724 | esac 725 | ]) 726 | 727 | # Helper functions for option handling. -*- Autoconf -*- 728 | 729 | # Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software 730 | # Foundation, Inc. 731 | # 732 | # This file is free software; the Free Software Foundation 733 | # gives unlimited permission to copy and/or distribute it, 734 | # with or without modifications, as long as this notice is preserved. 735 | 736 | # serial 5 737 | 738 | # _AM_MANGLE_OPTION(NAME) 739 | # ----------------------- 740 | AC_DEFUN([_AM_MANGLE_OPTION], 741 | [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) 742 | 743 | # _AM_SET_OPTION(NAME) 744 | # -------------------- 745 | # Set option NAME. Presently that only means defining a flag for this option. 746 | AC_DEFUN([_AM_SET_OPTION], 747 | [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) 748 | 749 | # _AM_SET_OPTIONS(OPTIONS) 750 | # ------------------------ 751 | # OPTIONS is a space-separated list of Automake options. 752 | AC_DEFUN([_AM_SET_OPTIONS], 753 | [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) 754 | 755 | # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) 756 | # ------------------------------------------- 757 | # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. 758 | AC_DEFUN([_AM_IF_OPTION], 759 | [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) 760 | 761 | # Check to make sure that the build environment is sane. -*- Autoconf -*- 762 | 763 | # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 764 | # Free Software Foundation, Inc. 765 | # 766 | # This file is free software; the Free Software Foundation 767 | # gives unlimited permission to copy and/or distribute it, 768 | # with or without modifications, as long as this notice is preserved. 769 | 770 | # serial 5 771 | 772 | # AM_SANITY_CHECK 773 | # --------------- 774 | AC_DEFUN([AM_SANITY_CHECK], 775 | [AC_MSG_CHECKING([whether build environment is sane]) 776 | # Just in case 777 | sleep 1 778 | echo timestamp > conftest.file 779 | # Reject unsafe characters in $srcdir or the absolute working directory 780 | # name. Accept space and tab only in the latter. 781 | am_lf=' 782 | ' 783 | case `pwd` in 784 | *[[\\\"\#\$\&\'\`$am_lf]]*) 785 | AC_MSG_ERROR([unsafe absolute working directory name]);; 786 | esac 787 | case $srcdir in 788 | *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) 789 | AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; 790 | esac 791 | 792 | # Do `set' in a subshell so we don't clobber the current shell's 793 | # arguments. Must try -L first in case configure is actually a 794 | # symlink; some systems play weird games with the mod time of symlinks 795 | # (eg FreeBSD returns the mod time of the symlink's containing 796 | # directory). 797 | if ( 798 | set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` 799 | if test "$[*]" = "X"; then 800 | # -L didn't work. 801 | set X `ls -t "$srcdir/configure" conftest.file` 802 | fi 803 | rm -f conftest.file 804 | if test "$[*]" != "X $srcdir/configure conftest.file" \ 805 | && test "$[*]" != "X conftest.file $srcdir/configure"; then 806 | 807 | # If neither matched, then we have a broken ls. This can happen 808 | # if, for instance, CONFIG_SHELL is bash and it inherits a 809 | # broken ls alias from the environment. This has actually 810 | # happened. Such a system could not be considered "sane". 811 | AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken 812 | alias in your environment]) 813 | fi 814 | 815 | test "$[2]" = conftest.file 816 | ) 817 | then 818 | # Ok. 819 | : 820 | else 821 | AC_MSG_ERROR([newly created file is older than distributed files! 822 | Check your system clock]) 823 | fi 824 | AC_MSG_RESULT(yes)]) 825 | 826 | # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. 827 | # 828 | # This file is free software; the Free Software Foundation 829 | # gives unlimited permission to copy and/or distribute it, 830 | # with or without modifications, as long as this notice is preserved. 831 | 832 | # serial 1 833 | 834 | # AM_PROG_INSTALL_STRIP 835 | # --------------------- 836 | # One issue with vendor `install' (even GNU) is that you can't 837 | # specify the program used to strip binaries. This is especially 838 | # annoying in cross-compiling environments, where the build's strip 839 | # is unlikely to handle the host's binaries. 840 | # Fortunately install-sh will honor a STRIPPROG variable, so we 841 | # always use install-sh in `make install-strip', and initialize 842 | # STRIPPROG with the value of the STRIP variable (set by the user). 843 | AC_DEFUN([AM_PROG_INSTALL_STRIP], 844 | [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl 845 | # Installed binaries are usually stripped using `strip' when the user 846 | # run `make install-strip'. However `strip' might not be the right 847 | # tool to use in cross-compilation environments, therefore Automake 848 | # will honor the `STRIP' environment variable to overrule this program. 849 | dnl Don't test for $cross_compiling = yes, because it might be `maybe'. 850 | if test "$cross_compiling" != no; then 851 | AC_CHECK_TOOL([STRIP], [strip], :) 852 | fi 853 | INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" 854 | AC_SUBST([INSTALL_STRIP_PROGRAM])]) 855 | 856 | # Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. 857 | # 858 | # This file is free software; the Free Software Foundation 859 | # gives unlimited permission to copy and/or distribute it, 860 | # with or without modifications, as long as this notice is preserved. 861 | 862 | # serial 3 863 | 864 | # _AM_SUBST_NOTMAKE(VARIABLE) 865 | # --------------------------- 866 | # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. 867 | # This macro is traced by Automake. 868 | AC_DEFUN([_AM_SUBST_NOTMAKE]) 869 | 870 | # AM_SUBST_NOTMAKE(VARIABLE) 871 | # -------------------------- 872 | # Public sister of _AM_SUBST_NOTMAKE. 873 | AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) 874 | 875 | # Check how to create a tarball. -*- Autoconf -*- 876 | 877 | # Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. 878 | # 879 | # This file is free software; the Free Software Foundation 880 | # gives unlimited permission to copy and/or distribute it, 881 | # with or without modifications, as long as this notice is preserved. 882 | 883 | # serial 2 884 | 885 | # _AM_PROG_TAR(FORMAT) 886 | # -------------------- 887 | # Check how to create a tarball in format FORMAT. 888 | # FORMAT should be one of `v7', `ustar', or `pax'. 889 | # 890 | # Substitute a variable $(am__tar) that is a command 891 | # writing to stdout a FORMAT-tarball containing the directory 892 | # $tardir. 893 | # tardir=directory && $(am__tar) > result.tar 894 | # 895 | # Substitute a variable $(am__untar) that extract such 896 | # a tarball read from stdin. 897 | # $(am__untar) < result.tar 898 | AC_DEFUN([_AM_PROG_TAR], 899 | [# Always define AMTAR for backward compatibility. Yes, it's still used 900 | # in the wild :-( We should find a proper way to deprecate it ... 901 | AC_SUBST([AMTAR], ['$${TAR-tar}']) 902 | m4_if([$1], [v7], 903 | [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], 904 | [m4_case([$1], [ustar],, [pax],, 905 | [m4_fatal([Unknown tar format])]) 906 | AC_MSG_CHECKING([how to create a $1 tar archive]) 907 | # Loop over all known methods to create a tar archive until one works. 908 | _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' 909 | _am_tools=${am_cv_prog_tar_$1-$_am_tools} 910 | # Do not fold the above two line into one, because Tru64 sh and 911 | # Solaris sh will not grok spaces in the rhs of `-'. 912 | for _am_tool in $_am_tools 913 | do 914 | case $_am_tool in 915 | gnutar) 916 | for _am_tar in tar gnutar gtar; 917 | do 918 | AM_RUN_LOG([$_am_tar --version]) && break 919 | done 920 | am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' 921 | am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' 922 | am__untar="$_am_tar -xf -" 923 | ;; 924 | plaintar) 925 | # Must skip GNU tar: if it does not support --format= it doesn't create 926 | # ustar tarball either. 927 | (tar --version) >/dev/null 2>&1 && continue 928 | am__tar='tar chf - "$$tardir"' 929 | am__tar_='tar chf - "$tardir"' 930 | am__untar='tar xf -' 931 | ;; 932 | pax) 933 | am__tar='pax -L -x $1 -w "$$tardir"' 934 | am__tar_='pax -L -x $1 -w "$tardir"' 935 | am__untar='pax -r' 936 | ;; 937 | cpio) 938 | am__tar='find "$$tardir" -print | cpio -o -H $1 -L' 939 | am__tar_='find "$tardir" -print | cpio -o -H $1 -L' 940 | am__untar='cpio -i -H $1 -d' 941 | ;; 942 | none) 943 | am__tar=false 944 | am__tar_=false 945 | am__untar=false 946 | ;; 947 | esac 948 | 949 | # If the value was cached, stop now. We just wanted to have am__tar 950 | # and am__untar set. 951 | test -n "${am_cv_prog_tar_$1}" && break 952 | 953 | # tar/untar a dummy directory, and stop if the command works 954 | rm -rf conftest.dir 955 | mkdir conftest.dir 956 | echo GrepMe > conftest.dir/file 957 | AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) 958 | rm -rf conftest.dir 959 | if test -s conftest.tar; then 960 | AM_RUN_LOG([$am__untar /dev/null 2>&1 && break 962 | fi 963 | done 964 | rm -rf conftest.dir 965 | 966 | AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) 967 | AC_MSG_RESULT([$am_cv_prog_tar_$1])]) 968 | AC_SUBST([am__tar]) 969 | AC_SUBST([am__untar]) 970 | ]) # _AM_PROG_TAR 971 | 972 | -------------------------------------------------------------------------------- /common.c: -------------------------------------------------------------------------------- 1 | #include "luvi.h" 2 | 3 | /* 4 | * Copy the parameters of the original video stream to the output codec. 5 | */ 6 | void init_codec(Context * ctx, AVCodecContext * CodecCtx, int slave) 7 | { 8 | CodecCtx->bit_rate = ctx->configuration.video_bit_rate; 9 | CodecCtx->width = ctx->configuration.width; 10 | CodecCtx->height = ctx->configuration.height; 11 | CodecCtx->pix_fmt = PIX_FMT_YUV420P; 12 | CodecCtx->sample_aspect_ratio.num = ctx->configuration.sample_aspect_ratio_num; 13 | CodecCtx->sample_aspect_ratio.den = ctx->configuration.sample_aspect_ratio_den; 14 | CodecCtx->time_base.num = ctx->configuration.avg_frame_rate_den; 15 | CodecCtx->time_base.den = ctx->configuration.avg_frame_rate_num; 16 | } 17 | 18 | struct addrinfo * gethost(char * name) 19 | { 20 | struct addrinfo * info, * result; 21 | int s; 22 | 23 | s = getaddrinfo(name, NULL, NULL, &result); 24 | 25 | if(s != 0 || result == NULL) { 26 | perror("getaddrinfo"); 27 | printf("Failed to lookup address: %s\n", name); 28 | exit(1); 29 | } 30 | 31 | return result; 32 | } 33 | 34 | /* 35 | * Open the output codec, supporting frame and configure it to our liking. 36 | */ 37 | int init_out(Context * ctx, int slave) 38 | { 39 | if(slave == 0) { 40 | //char * container = "mpegts"; 41 | char * container = "matroska"; 42 | 43 | if(avformat_alloc_output_context2(&ctx->outFormatCtx, NULL, container, NULL) < 0) { 44 | printf("Could not allocate output format context %s\n", container); 45 | return -1; 46 | } 47 | 48 | if(!ctx->outFormatCtx) { 49 | printf("Could not find suitable output format context %s\n", container); 50 | return -1; 51 | } 52 | } 53 | 54 | /* find the encoder */ 55 | ctx->outVideoCodec = avcodec_find_encoder(AV_CODEC_ID_H264); 56 | if (!(ctx->outVideoCodec)) { 57 | printf("Could not find video codec\n"); 58 | return -1; 59 | } 60 | 61 | if(ctx->configuration.audio_codec_id != -1) { 62 | /* find the encoder */ 63 | ctx->outAudioCodec = avcodec_find_encoder(ctx->configuration.audio_codec_id); 64 | if (!(ctx->outAudioCodec)) { 65 | printf("Could not find audio codec\n"); 66 | return -1; 67 | } 68 | } 69 | 70 | if(slave) { 71 | ctx->outVideoCodecCtx = avcodec_alloc_context3(ctx->outVideoCodec); 72 | 73 | if(ctx->outVideoCodecCtx == NULL) { 74 | printf("Failed to open output codec context\n"); 75 | return -1; 76 | } 77 | 78 | } else { 79 | ctx->outVideoStream = avformat_new_stream(ctx->outFormatCtx, ctx->outVideoCodec); 80 | if (!ctx->outVideoStream) { 81 | printf("Could not allocate output video stream\n"); 82 | return -1; 83 | } 84 | 85 | ctx->outVideoStream->id = ctx->outFormatCtx->nb_streams - 1; 86 | printf("Output video stream id: %d\n", ctx->outVideoStream->id); 87 | 88 | ctx->outVideoCodecCtx = ctx->outVideoStream->codec; 89 | 90 | if(ctx->configuration.audio_codec_id != -1) { 91 | ctx->outAudioStream = avformat_new_stream(ctx->outFormatCtx, ctx->outAudioCodec); 92 | if (!ctx->outAudioStream) { 93 | printf("Could not allocate stream\n"); 94 | return -1; 95 | } 96 | 97 | /* Consider copying *all* the audio streams and subtitles.... */ 98 | 99 | ctx->outAudioStream->id = ctx->outFormatCtx->nb_streams-1; 100 | ctx->outAudioCodecCtx = ctx->outAudioStream->codec; 101 | 102 | printf("Output audio stream id: %d\n", ctx->outAudioStream->id); 103 | 104 | avcodec_copy_context(ctx->outAudioCodecCtx, ctx->inAudioStream->codec); 105 | 106 | av_dict_set(&ctx->outAudioStream->metadata, "language", 107 | av_dict_get(ctx->inAudioStream->metadata, "language", NULL, 0)->value, 0); 108 | 109 | ctx->outAudioCodecCtx->sample_rate = ctx->configuration.audio_sample_rate; 110 | ctx->outAudioCodecCtx->bit_rate = ctx->configuration.audio_bit_rate; 111 | ctx->outAudioCodecCtx->sample_fmt = ctx->configuration.audio_sample_format; 112 | ctx->outAudioCodecCtx->frame_size = ctx->configuration.audio_frame_size; 113 | ctx->outAudioCodecCtx->channels = ctx->configuration.audio_channels; 114 | ctx->outAudioCodecCtx->audio_service_type = ctx->configuration.audio_service_type; 115 | } 116 | } 117 | 118 | /* 119 | * Mmmmm.... let's make a bluray disc. 120 | */ 121 | 122 | /* 123 | * 124 | * THESE SETTINGS WORK LOCAL. TESTED IN PLAYER> 125 | * 126 | avcodec_get_context_defaults3(ctx->outVideoCodecCtx, ctx->outVideoCodec); 127 | av_opt_set(ctx->outVideoCodecCtx->priv_data, "tune", "zerolatency", 0); 128 | av_opt_set(ctx->outVideoCodecCtx->priv_data, "preset", "ultrafast", 0); 129 | av_opt_set(ctx->outVideoCodecCtx->priv_data, "x264opts", "bitrate=7000:bluray-compat=1:tff=1:vbv_maxrate=40000:vbv_bufsize=30000:keyint=30:open-gop=1:fake-interlaced=1:slices=4:colorprim=bt709:transfer=bt709:colormatrix=bt709:level=4.1", 0); 130 | */ 131 | 132 | /* 133 | * DEVELOPMENT SETTINGS 134 | */ 135 | avcodec_get_context_defaults3(ctx->outVideoCodecCtx, ctx->outVideoCodec); 136 | av_opt_set(ctx->outVideoCodecCtx->priv_data, "tune", "zerolatency", 0); 137 | av_opt_set(ctx->outVideoCodecCtx->priv_data, "preset", "ultrafast", 0); 138 | av_opt_set(ctx->outVideoCodecCtx->priv_data, "x264opts", "bitrate=7000:bluray-compat=1:tff=1:vbv_maxrate=40000:vbv_bufsize=30000:keyint=30:open-gop=1:fake-interlaced=1:slices=4:colorprim=bt709:transfer=bt709:colormatrix=bt709:level=4.1", 0); 139 | 140 | 141 | init_codec(ctx, ctx->outVideoCodecCtx, slave); 142 | 143 | /* open the codec */ 144 | if (avcodec_open2(ctx->outVideoCodecCtx, ctx->outVideoCodec, NULL) < 0) { 145 | printf("Could not open output video codec\n"); 146 | return -1; 147 | } 148 | 149 | printf("Opened output video codec %s\n", avcodec_get_name(ctx->outVideoCodecCtx->codec_id)); 150 | 151 | ctx->outVideoFrame = avcodec_alloc_frame(); 152 | if (!ctx->outVideoFrame) { 153 | printf("Could not allocate video frame\n"); 154 | return -1; 155 | } 156 | 157 | // Determine required buffer size and allocate buffer 158 | if(avpicture_alloc(&ctx->outPicture, ctx->outVideoCodecCtx->pix_fmt, ctx->outVideoCodecCtx->width, ctx->outVideoCodecCtx->height) < 0) { 159 | printf("Could not allocate output picture\n"); 160 | return -1; 161 | } 162 | 163 | *((AVPicture *)ctx->outVideoFrame) = ctx->outPicture; 164 | 165 | return 0; 166 | } 167 | 168 | /* 169 | * Open the input codec based on the ID used by the source file. 170 | */ 171 | int init_in(Context * ctx, int slave) 172 | { 173 | int x = 0; 174 | // Find the decoder for the video stream 175 | ctx->inVideoCodec = avcodec_find_decoder(ctx->configuration.video_codec_id); 176 | 177 | if(!ctx->inVideoCodec) { 178 | printf("Unsupported video codec!\n"); 179 | return -1; 180 | } 181 | 182 | ctx->inVideoCodecCtx = avcodec_alloc_context3(ctx->inVideoCodec); 183 | 184 | if(!ctx->inVideoCodecCtx) { 185 | printf("Failed to allocate video codec context\n"); 186 | return -1; 187 | } 188 | 189 | // Open codec 190 | if(avcodec_open2(ctx->inVideoCodecCtx, ctx->inVideoCodec, NULL) < 0) { 191 | printf("Could not open input video codec\n"); 192 | return -1; 193 | } 194 | 195 | printf("Opened input video codec %s\n", avcodec_get_name(ctx->inVideoCodecCtx->codec_id)); 196 | 197 | ctx->inVideoFrame = avcodec_alloc_frame(); 198 | 199 | return 0; 200 | } 201 | 202 | void destroy_ctx(Context * ctx) 203 | { 204 | int x; 205 | 206 | if(ctx->xdo) 207 | xdo_free(ctx->xdo); 208 | 209 | for(x = 0; x < MAX_SLAVES; x++) 210 | queueDelete(ctx->slaves[x].results); 211 | 212 | queueDelete (ctx->in_fifo); 213 | queueDelete (ctx->out_fifo); 214 | 215 | destroy_ctx_out(ctx); 216 | destroy_ctx_in(ctx); 217 | 218 | free(ctx); 219 | } 220 | /* 221 | * Default settings for private master/slave variables. 222 | */ 223 | int init_ctx(Context * ctx, int queuesize) 224 | { 225 | int x; 226 | 227 | if(gethostname(ctx->hostname, 100) != 0) { 228 | perror("gethostname"); 229 | printf("Failed to get my own hostname =("); 230 | return -1; 231 | } 232 | 233 | config__init(&ctx->configuration); 234 | 235 | ctx->configuration.audio_codec_id = -1; 236 | 237 | for(x = 0; x < MAX_SLAVES; x++) { 238 | ctx->slaves[x].ranges = 0; 239 | ctx->slaves[x].busy = 0; 240 | ctx->slaves[x].results = queueInit (QUEUESIZE); 241 | } 242 | 243 | ctx->fps = 0; 244 | ctx->videoStream = -1; 245 | ctx->audioStream = -1; 246 | ctx->xdo = xdo_new(":0.0"); 247 | if(ctx->xdo) 248 | xdo_keysequence(ctx->xdo, CURRENTWINDOW, "Shift_L", 0); 249 | ctx->curr_slave = NULL; 250 | ctx->num_slaves = 0; 251 | ctx->ready_for_slaves = 0; 252 | //ctx->ready_for_slaves = 1; 253 | ctx->drops_stopped = 0; 254 | //ctx->drops_stopped = 1; 255 | //ctx->encoder_clean = 0; 256 | ctx->encoder_clean = 1; 257 | 258 | ctx->stop_in_consumer = 0; 259 | ctx->stop_out_consumer = 0; 260 | ctx->stop_listener = 0; 261 | ctx->first_keyframe_reached = 0; 262 | av_register_all(); 263 | 264 | ctx->in_fifo = queueInit (queuesize); 265 | if (ctx->in_fifo == NULL) { 266 | printf("main: Input Queue Init failed.\n"); 267 | exit (1); 268 | } 269 | 270 | ctx->out_fifo = queueInit (queuesize); 271 | if (ctx->out_fifo == NULL) { 272 | printf("main: Output Queue Init failed.\n"); 273 | exit (1); 274 | } 275 | 276 | ctx->outFormatCtx = NULL; 277 | ctx->inFormatCtx = NULL; 278 | ctx->outVideoCodecCtx = NULL; 279 | ctx->inVideoCodecCtx = NULL; 280 | ctx->outAudioCodecCtx = NULL; 281 | ctx->outVideoCodec = NULL; 282 | ctx->inVideoCodec = NULL; 283 | ctx->outAudioCodec = NULL; 284 | ctx->outVideoFrame = NULL; 285 | ctx->inVideoFrame = NULL; 286 | ctx->inVideoStream = NULL; 287 | ctx->outVideoStream = NULL; 288 | ctx->inAudioStream = NULL; 289 | ctx->outAudioStream = NULL; 290 | 291 | return 0; 292 | } 293 | 294 | /* 295 | * Get our transcoding game on... 296 | * 297 | * This function was designed to be completely parallel. 298 | * Frames are not sent to the slaves until the decoder becomes 299 | * deterministic - meaning that the decoder gets primed with some 300 | * initial packets from the input video stream. 301 | * 302 | * Once the decoder starts predictably giving us 1 frame for every 303 | * input packet, we're good to go and start sending out the packets 304 | * to the slaves. 305 | * 306 | * For a handful of packets, this function gets called by the master 307 | * and then we go full blast on all the slaves. 308 | */ 309 | int transcode(Context * ctx, queue_entry_t * e, Convert * convert, AVPacket * packet) 310 | { 311 | static long decode = 0, 312 | encode = 0, 313 | dups = 0, 314 | drops = 0, 315 | single = 0, 316 | write = 0; 317 | int * buffers = &(convert->buffers), 318 | * extra_frame_count = &(convert->extra_frame_count), 319 | nFrameCount = convert->n_frame_count, 320 | z = 0, 321 | ret = 0, 322 | frameFinished = 0; 323 | int64_t frame_number = convert->frame_number, 324 | orig_pts = packet->pts, 325 | orig_dts = packet->pts; 326 | struct timeval dstart, 327 | dstop, 328 | ddiff, 329 | estart, 330 | estop, 331 | ediff; 332 | 333 | *extra_frame_count = 0; 334 | *buffers = 0; 335 | 336 | avcodec_get_frame_defaults(ctx->inVideoFrame); 337 | 338 | if(debug == 3) 339 | gettimeofday(&dstart, NULL); 340 | 341 | if(avcodec_decode_video2(ctx->inVideoCodecCtx, ctx->inVideoFrame, &frameFinished, packet) < 0) { 342 | printf("Error decoding dts %" PRId64 "\n", packet->dts); 343 | exit(1); 344 | } 345 | 346 | if(debug == 3) { 347 | gettimeofday(&dstop, NULL); 348 | timersub(&dstop, &dstart, &ddiff); 349 | decode += (USEC(ddiff) / 1000); 350 | } 351 | 352 | /* 353 | * If we're not done yet (should only happen in the beginning), 354 | * Tell the master. 355 | */ 356 | if(!frameFinished) { 357 | if(debug == 2) 358 | printf("skipping pts %" PRId64 " dts %" PRId64 "\n", packet->pts, packet->dts); 359 | return 0; 360 | } else { 361 | if(debug == 2) 362 | printf("finished pts %" PRId64 " dts %" PRId64 "\n", orig_pts, orig_dts); 363 | } 364 | 365 | /* 366 | * Tally the dropped and duplicated frames. 367 | */ 368 | if (nFrameCount == 0) { 369 | drops++; 370 | } else if (nFrameCount > 1) { 371 | dups += (nFrameCount - 1); 372 | single++; 373 | } else { 374 | single++; 375 | } 376 | 377 | /* 378 | * Copy the decoded frame into a new frame for encoding. 379 | * 380 | * FIXME: Is this necessary? Can I juse re-encode the original? 381 | */ 382 | av_picture_copy((AVPicture*)ctx->outVideoFrame,(AVPicture*)ctx->inVideoFrame,ctx->outVideoCodecCtx->pix_fmt, ctx->outVideoCodecCtx->width,ctx->outVideoCodecCtx->height); 383 | 384 | /* 385 | * Encode, taking duplicates into account. 386 | */ 387 | for (z = 0; z < nFrameCount && z < 10; z++) 388 | { 389 | if(debug==2) 390 | printf("INpkt Frame %" PRId64 " dts: %" PRId64 " pts: %" PRId64 "\n", frame_number, orig_dts, orig_pts); 391 | 392 | /* 393 | * Sometimes the encoder doesn't finish in one sitting... 394 | */ 395 | do { 396 | ctx->outVideoFrame->pts = frame_number; 397 | ctx->outVideoFrame->pict_type = 0; 398 | 399 | if(debug == 3) 400 | gettimeofday(&estart, NULL); 401 | 402 | e->outBuffers[z] = av_malloc(MAX_PACKET); 403 | assert(e->outBuffers[z]); 404 | ret = avcodec_encode_video(ctx->outVideoCodecCtx, e->outBuffers[z], MAX_PACKET, ctx->outVideoFrame); 405 | 406 | if(debug == 3) { 407 | gettimeofday(&estop, NULL); 408 | timersub(&estop, &estart, &ediff); 409 | encode += (USEC(ediff) / 1000); 410 | } 411 | 412 | if(ret < 0) { 413 | printf("Error encoding frame\n"); 414 | exit(1); 415 | } 416 | if(ret == 0) { 417 | /* 418 | * If the encoder is not yet deterministic either, 419 | * then take note of it. 420 | */ 421 | *extra_frame_count = *extra_frame_count + 1; 422 | frame_number++; 423 | if(debug==2) 424 | printf("not finished, bumping frame_number to %" PRId64 "\n", frame_number); 425 | } 426 | } while(ret == 0); 427 | 428 | if (ret > 0) { 429 | /* 430 | * Save all the meta-data of the newly transcoded frame for transmission to master. 431 | */ 432 | e->buffer_lengths[z] = ret; 433 | e->flags[z] = 0; 434 | e->pts[z] = AV_NOPTS_VALUE; 435 | e->dts[z] = AV_NOPTS_VALUE; 436 | 437 | if(ctx->outVideoCodecCtx->coded_frame && ctx->outVideoCodecCtx->coded_frame->key_frame) 438 | e->flags[z] |= AV_PKT_FLAG_KEY; 439 | 440 | /* 441 | * Proper time-base conversion. 442 | */ 443 | if (ctx->outVideoCodecCtx->coded_frame && ctx->outVideoCodecCtx->coded_frame->pts != AV_NOPTS_VALUE) 444 | { 445 | AVRational stream_time_base = {.num = ctx->configuration.stream_time_base_num, .den = ctx->configuration.stream_time_base_den }; 446 | e->pts[z] = av_rescale_q(ctx->outVideoFrame->pts, ctx->outVideoCodecCtx->time_base, stream_time_base); 447 | if(debug == 2) 448 | printf("MUX: Rescaled video PTS from %" PRId64 " (codec time_base) to %" PRId64 " (stream time_base) outframe pts %" PRId64 " frame number %" PRId64 ".\n", ctx->outVideoCodecCtx->coded_frame->pts, e->pts[z], ctx->outVideoFrame->pts, frame_number); 449 | } 450 | 451 | /* FIXME: Is this correct? */ 452 | e->dts[z] = e->pts[z]; 453 | 454 | if(debug == 2) 455 | printf("MUX: (%" PRId64 ") queue %d, Writing video frame with PTS: %" PRId64 " DTS %" PRId64 ".\n", frame_number, ctx->in_fifo->size, e->pts[z], e->dts[z]); 456 | 457 | if((frame_number % (int) ctx->configuration.avg_framerate) == 0) { 458 | /* 459 | * Nice library to make sure the slave computer does not go to sleep while we are 460 | * transcoding by simulating a harmless keystroke on the display. 461 | */ 462 | if(ctx->xdo && ((frame_number % 10) == 0)) { 463 | printf("\nEmitting shift keypress to keep machine alive\n"); 464 | xdo_keysequence(ctx->xdo, CURRENTWINDOW, "Shift_L", 0); 465 | } 466 | 467 | printf("\r(%1.1f %%) (%" PRId64 ") queue %d dups %ld single %ld drops %ld", 468 | (frame_number / ctx->configuration.expected_total_frames) * 100, 469 | frame_number, 470 | ctx->in_fifo->size, 471 | dups, single, drops); 472 | printf(" (size=%5d) pts %" PRId64 " dts %" PRId64 " ", e->buffer_lengths[z], e->pts[z], e->dts[z]); 473 | printf(" decode %ld encode %ld fps %f =======", decode, encode, ctx->fps); 474 | fflush(stdout); 475 | } 476 | 477 | } 478 | 479 | frame_number++; 480 | } 481 | 482 | *buffers = z; 483 | } 484 | 485 | /* 486 | * Close everything properly to get resulting x264 statistics. 487 | */ 488 | void destroy_ctx_in(Context * ctx) 489 | { 490 | avcodec_free_frame(&ctx->inVideoFrame); 491 | if(ctx->inVideoCodecCtx) 492 | avcodec_close(ctx->inVideoCodecCtx); 493 | } 494 | 495 | void destroy_ctx_out(Context * ctx) 496 | { 497 | if(ctx->outVideoCodecCtx) 498 | avcodec_close(ctx->outVideoCodecCtx); 499 | if(ctx->outAudioCodecCtx) 500 | avcodec_close(ctx->outAudioCodecCtx); 501 | av_free(ctx->outFormatCtx); 502 | avcodec_free_frame(&ctx->outVideoFrame); 503 | } 504 | 505 | /* 506 | * Send/Receive functions for transmitting 507 | * using protocol buffers. 508 | */ 509 | 510 | int cmdsend(int fd, void * buf, Command * cmd) 511 | { 512 | char * desc = describe[cmd->code]; 513 | int ret; 514 | unsigned short len = command__get_packed_size(cmd), 515 | nlen = htons(len); 516 | 517 | if(len > MAX_MSG_SIZE) { 518 | printf("send protobuf is too big for buffer %u: %s fd %d\n", len, desc, fd); 519 | exit(1); 520 | } 521 | 522 | ret = multiwrite(fd, (uint8_t*) &nlen, sizeof(nlen)); 523 | if(ret <= 0) { 524 | printf("Failed to send protobuf length %u: %s fd %d\n", len, desc, fd); 525 | perror("send"); 526 | exit(1); 527 | } 528 | 529 | command__pack(cmd, buf); 530 | ret = multiwrite(fd, buf, len); 531 | 532 | if(ret <= 0) { 533 | printf("Failure: send: %s fd %d\n", desc, fd); 534 | perror("send"); 535 | exit(1); 536 | } 537 | 538 | if(ret != len) { 539 | printf("Failure send fd %d: %s is too small: %d\n", fd, desc, ret); 540 | exit(1); 541 | } 542 | 543 | 544 | return ret; 545 | } 546 | 547 | /* 548 | * Taking care to handle incomplete transmissions and non-blocking I/O. 549 | */ 550 | 551 | int multiwrite(int fd, uint8_t * packet_data, int remaining) 552 | { 553 | int total = 0; 554 | int ret; 555 | 556 | do { 557 | ret = write(fd, packet_data + total, remaining); 558 | 559 | if(ret == -1 && errno == EAGAIN) { 560 | fd_set wait_for_write; 561 | FD_ZERO(&wait_for_write); 562 | FD_SET(fd, &wait_for_write); 563 | ret = select(fd + 1, NULL, &wait_for_write, NULL, NULL); 564 | if(ret < 0) { 565 | printf("failed to deail with non blocking write!\n"); 566 | return ret; 567 | } 568 | 569 | ret = write(fd, packet_data + total, remaining); 570 | } 571 | 572 | if(ret < 0) { 573 | perror("multiwrite packet"); 574 | printf("Failed to write packet data %d\n", ret); 575 | return ret; 576 | } 577 | if(ret == 0) { 578 | perror("multiwrite packet"); 579 | printf("disconnected multiwrite\n"); 580 | return 0; 581 | } 582 | remaining -= ret; 583 | total += ret; 584 | } while(remaining > 0); 585 | 586 | return total; 587 | } 588 | 589 | int multirecv(int fd, uint8_t * packet_data, int remaining) 590 | { 591 | int total = 0; 592 | int ret; 593 | 594 | do { 595 | ret = read(fd, packet_data + total, remaining); 596 | 597 | if(ret == -1 && errno == EAGAIN) { 598 | fd_set wait_for_read; 599 | FD_ZERO(&wait_for_read); 600 | FD_SET(fd, &wait_for_read); 601 | ret = select(fd + 1, &wait_for_read, NULL, NULL, NULL); 602 | if(ret < 0) { 603 | printf("failed to deal with non blocking read!\n"); 604 | return ret; 605 | } 606 | 607 | ret = read(fd, packet_data + total, remaining); 608 | } 609 | if(ret < 0) { 610 | perror("multirecv packet"); 611 | printf("Failed to receive packet data %d\n", ret); 612 | return ret; 613 | } 614 | if(ret == 0) { 615 | perror("multirecv packet"); 616 | printf("disconnected multirecv\n"); 617 | return 0; 618 | } 619 | remaining -= ret; 620 | total += ret; 621 | } while(remaining > 0); 622 | 623 | return total; 624 | } 625 | 626 | int cmdrecv(int fd, void * buf, Command ** dest, int32_t expecting) { 627 | char * expecting_desc = describe[expecting]; 628 | int ret; 629 | unsigned short len, nlen; 630 | Command * cmd; 631 | 632 | ret = multirecv(fd, (uint8_t *) &nlen, sizeof(nlen)); 633 | 634 | if(ret <= 0) { 635 | printf("Failure: recv: could not determine command length %s\n", expecting_desc); 636 | perror("recv"); 637 | exit(1); 638 | } 639 | 640 | len = ntohs(nlen); 641 | 642 | // printf("Receiving protobuf of length: %u\n", len); 643 | 644 | if(len > MAX_MSG_SIZE) { 645 | printf("receive protobuf is too big for buffer %u: %s fd %d\n", len, expecting_desc, fd); 646 | exit(1); 647 | } 648 | 649 | ret = multirecv(fd, buf, len); 650 | 651 | if(ret <= 0) { 652 | printf("cmdrecv multirecv failure: %s\n", expecting_desc); 653 | exit(1); 654 | } 655 | 656 | if(ret != len) { 657 | printf("Failure recv: %s is too small: %d\n", expecting_desc, ret); 658 | exit(1); 659 | } 660 | 661 | cmd = command__unpack(NULL, len, buf); 662 | 663 | if(cmd == NULL) { 664 | printf("Failed to unpack protocol buffer: expecting %s (%d) len %d\n", expecting_desc, expecting, len); 665 | exit(1); 666 | } 667 | 668 | if(cmd->code < 0 || cmd->code >= CMDLEN) { 669 | printf("Received Command code is corrupted: %d, expecting %s (%d)\n", cmd->code, expecting_desc, expecting); 670 | exit(1); 671 | } 672 | 673 | if(expecting != cmd->code) { 674 | char * desc = describe[cmd->code]; 675 | printf("recv: Was expecting %s (%d) but got %s (%d) instead. Bailing.\n", expecting_desc, expecting, desc, cmd->code); 676 | exit(1); 677 | } 678 | 679 | *dest = cmd; 680 | 681 | return ret; 682 | } 683 | 684 | #define COPY_PACKET_VALUES(dest, src) \ 685 | do { \ 686 | dest->pts = src->pts; \ 687 | dest->dts = src->dts; \ 688 | dest->size = src->size; \ 689 | dest->stream_index = src->stream_index; \ 690 | dest->flags = src->flags; \ 691 | dest->duration = src->duration; \ 692 | dest->pos = src->pos; \ 693 | dest->convergence_duration = src->convergence_duration; \ 694 | } while(0) 695 | 696 | void packet_to_protobuf(Packet * dest, AVPacket * src) 697 | { 698 | COPY_PACKET_VALUES(dest, src); 699 | } 700 | void protobuf_to_packet(AVPacket * dest, Packet * src) 701 | { 702 | COPY_PACKET_VALUES(dest, src); 703 | } 704 | 705 | void store_transcode_result(Command * send, queue_entry_t * e) 706 | { 707 | if(!send->convert->buffers) 708 | return; 709 | 710 | send->convert->values = &e->values; 711 | values__init(send->convert->values); 712 | send->convert->values->n_pts = send->convert->buffers; 713 | send->convert->values->n_dts = send->convert->buffers; 714 | send->convert->values->n_buffer_lengths = send->convert->buffers; 715 | send->convert->values->n_flags = send->convert->buffers; 716 | 717 | send->convert->values->pts = e->pts; 718 | send->convert->values->dts = e->dts; 719 | send->convert->values->buffer_lengths = e->buffer_lengths; 720 | send->convert->values->flags = e->flags; 721 | } 722 | 723 | /* 724 | * Multi-threaded queue management routines. 725 | */ 726 | queue *queueInit (int queuesize) 727 | { 728 | queue *q; 729 | 730 | q = (queue *) malloc (sizeof (queue)); 731 | if (q == NULL) return (NULL); 732 | 733 | q->max = queuesize; 734 | q->cmds = malloc(sizeof(queue_entry_t) * q->max); 735 | q->empty = 1; 736 | q->full = 0; 737 | q->head = 0; 738 | q->tail = 0; 739 | q->size = 0; 740 | q->mut = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t)); 741 | pthread_mutex_init (q->mut, NULL); 742 | q->notFull = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); 743 | pthread_cond_init (q->notFull, NULL); 744 | q->notEmpty = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); 745 | pthread_cond_init (q->notEmpty, NULL); 746 | 747 | return (q); 748 | } 749 | 750 | void queueDelete (queue *q) 751 | { 752 | pthread_mutex_destroy (q->mut); 753 | free (q->mut); 754 | pthread_cond_destroy (q->notFull); 755 | free (q->notFull); 756 | pthread_cond_destroy (q->notEmpty); 757 | free (q->notEmpty); 758 | free (q->cmds); 759 | free (q); 760 | } 761 | 762 | void queueAdd (queue *q, queue_entry_t * in) 763 | { 764 | q->cmds[q->tail] = in; 765 | q->tail++; 766 | if (q->tail == q->max) 767 | q->tail = 0; 768 | if (q->tail == q->head) 769 | q->full = 1; 770 | q->empty = 0; 771 | q->size++; 772 | } 773 | 774 | queue_entry_t * queueHead(queue *q) { 775 | if(q->empty) 776 | return NULL; 777 | return q->cmds[q->head]; 778 | } 779 | 780 | void queueDel (queue *q, queue_entry_t ** out) 781 | { 782 | *out = q->cmds[q->head]; 783 | 784 | q->cmds[q->head] = NULL; 785 | q->head++; 786 | if (q->head == q->max) 787 | q->head = 0; 788 | if (q->head == q->tail) 789 | q->empty = 1; 790 | q->full = 0; 791 | q->size--; 792 | } 793 | 794 | void push(queue * fifo, queue_entry_t * e) 795 | { 796 | pthread_mutex_lock(fifo->mut); 797 | while(fifo->full) { 798 | printf("\nQueue is full %d max %d\n", fifo->size, fifo->max); 799 | pthread_cond_wait(fifo->notFull, fifo->mut); 800 | printf("\nNot full anymore... %d max %d\n", fifo->size, fifo->max); 801 | } 802 | queueAdd(fifo, e); 803 | pthread_mutex_unlock(fifo->mut); 804 | pthread_cond_signal(fifo->notEmpty); 805 | } 806 | 807 | void in_consumer_stop(Context * ctx) 808 | { 809 | ctx->stop_in_consumer = 1; 810 | pthread_cond_signal(ctx->in_fifo->notEmpty); 811 | pthread_join(ctx->in_consumer, NULL); 812 | } 813 | 814 | void out_consumer_stop(Context * ctx) 815 | { 816 | ctx->stop_out_consumer = 1; 817 | pthread_cond_signal(ctx->out_fifo->notEmpty); 818 | pthread_join(ctx->out_consumer, NULL); 819 | } 820 | 821 | queue_entry_t * pop(queue * fifo, int * stop) 822 | { 823 | queue_entry_t * e; 824 | pthread_mutex_lock (fifo->mut); 825 | while (fifo->empty) { 826 | if(stop && *stop) { 827 | pthread_mutex_unlock (fifo->mut); 828 | return NULL; 829 | } 830 | 831 | pthread_cond_wait (fifo->notEmpty, fifo->mut); 832 | } 833 | 834 | queueDel(fifo, &e); 835 | pthread_mutex_unlock (fifo->mut); 836 | pthread_cond_signal (fifo->notFull); 837 | return e; 838 | } 839 | 840 | void update_fps(Context * ctx, int init) 841 | { 842 | static struct timeval start, stop, diff; 843 | static long frames = 0, oldframes = 0; 844 | 845 | if(init) { 846 | gettimeofday(&start, NULL); 847 | return; 848 | } 849 | 850 | frames++; 851 | 852 | if((frames % 1000) == 0) { 853 | gettimeofday(&stop, NULL); 854 | timersub(&stop, &start, &diff); 855 | if(diff.tv_sec > 0) { 856 | double time = ((double) USEC(diff)) / 1000000.0; 857 | double total = frames - oldframes; 858 | ctx->fps = total / time; 859 | printf("%f frames per second %f %f.\n", 860 | ctx->fps, 861 | time, 862 | total); 863 | } else { 864 | printf("differences is zero.\n"); 865 | } 866 | oldframes = frames; 867 | start = stop; 868 | } 869 | } 870 | 871 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Define to 1 if you have the header file. */ 4 | #undef HAVE_ARPA_INET_H 5 | 6 | /* Define to 1 if you have the header file. */ 7 | #undef HAVE_ASSERT_H 8 | 9 | /* Define to 1 if you have the `bzero' function. */ 10 | #undef HAVE_BZERO 11 | 12 | /* Define to 1 if you have the header file. */ 13 | #undef HAVE_FCNTL_H 14 | 15 | /* Define to 1 if you have the `gettimeofday' function. */ 16 | #undef HAVE_GETTIMEOFDAY 17 | 18 | /* Define to 1 if you have the `inet_ntoa' function. */ 19 | #undef HAVE_INET_NTOA 20 | 21 | /* Define to 1 if you have the header file. */ 22 | #undef HAVE_INTTYPES_H 23 | 24 | /* Define to 1 if you have the `avcodec' library (-lavcodec). */ 25 | #undef HAVE_LIBAVCODEC 26 | 27 | /* Define to 1 if you have the header file. */ 28 | #undef HAVE_LIBAVCODEC_AVCODEC_H 29 | 30 | /* Define to 1 if you have the `avformat' library (-lavformat). */ 31 | #undef HAVE_LIBAVFORMAT 32 | 33 | /* Define to 1 if you have the header file. */ 34 | #undef HAVE_LIBAVFORMAT_AVFORMAT_H 35 | 36 | /* Define to 1 if you have the `avutil' library (-lavutil). */ 37 | #undef HAVE_LIBAVUTIL 38 | 39 | /* Define to 1 if you have the header file. */ 40 | #undef HAVE_LIBAVUTIL_OPT_H 41 | 42 | /* Define to 1 if you have the `bz2' library (-lbz2). */ 43 | #undef HAVE_LIBBZ2 44 | 45 | /* Define to 1 if you have the `m' library (-lm). */ 46 | #undef HAVE_LIBM 47 | 48 | /* Define to 1 if you have the `protobuf-c' library (-lprotobuf-c). */ 49 | #undef HAVE_LIBPROTOBUF_C 50 | 51 | /* Define to 1 if you have the `pthread' library (-lpthread). */ 52 | #undef HAVE_LIBPTHREAD 53 | 54 | /* Define to 1 if you have the header file. */ 55 | #undef HAVE_LIBSWSCALE_SWSCALE_H 56 | 57 | /* Define to 1 if you have the `va' library (-lva). */ 58 | #undef HAVE_LIBVA 59 | 60 | /* Define to 1 if you have the `x264' library (-lx264). */ 61 | #undef HAVE_LIBX264 62 | 63 | /* Define to 1 if you have the `xdo' library (-lxdo). */ 64 | #undef HAVE_LIBXDO 65 | 66 | /* Define to 1 if you have the `z' library (-lz). */ 67 | #undef HAVE_LIBZ 68 | 69 | /* Define to 1 if your system has a GNU libc compatible `malloc' function, and 70 | to 0 otherwise. */ 71 | #undef HAVE_MALLOC 72 | 73 | /* Define to 1 if you have the header file. */ 74 | #undef HAVE_MEMORY_H 75 | 76 | /* Define to 1 if you have the header file. */ 77 | #undef HAVE_NETDB_H 78 | 79 | /* Define to 1 if you have the header file. */ 80 | #undef HAVE_NETINET_IN_H 81 | 82 | /* Define to 1 if you have the header file. */ 83 | #undef HAVE_PTHREAD_H 84 | 85 | /* Define to 1 if you have the `select' function. */ 86 | #undef HAVE_SELECT 87 | 88 | /* Define to 1 if you have the header file. */ 89 | #undef HAVE_SIGNAL_H 90 | 91 | /* Define to 1 if you have the `socket' function. */ 92 | #undef HAVE_SOCKET 93 | 94 | /* Define to 1 if you have the header file. */ 95 | #undef HAVE_STDINT_H 96 | 97 | /* Define to 1 if you have the header file. */ 98 | #undef HAVE_STDIO_H 99 | 100 | /* Define to 1 if you have the header file. */ 101 | #undef HAVE_STDLIB_H 102 | 103 | /* Define to 1 if you have the header file. */ 104 | #undef HAVE_STRINGS_H 105 | 106 | /* Define to 1 if you have the header file. */ 107 | #undef HAVE_STRING_H 108 | 109 | /* Define to 1 if you have the header file. */ 110 | #undef HAVE_SYS_MMAN_H 111 | 112 | /* Define to 1 if you have the header file. */ 113 | #undef HAVE_SYS_SOCKET_H 114 | 115 | /* Define to 1 if you have the header file. */ 116 | #undef HAVE_SYS_STAT_H 117 | 118 | /* Define to 1 if you have the header file. */ 119 | #undef HAVE_SYS_TIME_H 120 | 121 | /* Define to 1 if you have the header file. */ 122 | #undef HAVE_SYS_TYPES_H 123 | 124 | /* Define to 1 if you have the header file. */ 125 | #undef HAVE_UNISTD_H 126 | 127 | /* Define to 1 if you have the header file. */ 128 | #undef HAVE_X11_XLIB_H 129 | 130 | /* Define to 1 if you have the header file. */ 131 | #undef HAVE_XDO_H 132 | 133 | /* Name of package */ 134 | #undef PACKAGE 135 | 136 | /* Define to the address where bug reports for this package should be sent. */ 137 | #undef PACKAGE_BUGREPORT 138 | 139 | /* Define to the full name of this package. */ 140 | #undef PACKAGE_NAME 141 | 142 | /* Define to the full name and version of this package. */ 143 | #undef PACKAGE_STRING 144 | 145 | /* Define to the one symbol short name of this package. */ 146 | #undef PACKAGE_TARNAME 147 | 148 | /* Define to the home page for this package. */ 149 | #undef PACKAGE_URL 150 | 151 | /* Define to the version of this package. */ 152 | #undef PACKAGE_VERSION 153 | 154 | /* Define to 1 if you have the ANSI C header files. */ 155 | #undef STDC_HEADERS 156 | 157 | /* Version number of package */ 158 | #undef VERSION 159 | 160 | /* Define for Solaris 2.5.1 so the uint64_t typedef from , 161 | , or is not used. If the typedef were allowed, the 162 | #define below would cause a syntax error. */ 163 | #undef _UINT64_T 164 | 165 | /* Define for Solaris 2.5.1 so the uint8_t typedef from , 166 | , or is not used. If the typedef were allowed, the 167 | #define below would cause a syntax error. */ 168 | #undef _UINT8_T 169 | 170 | /* Define to the type of a signed integer type of width exactly 32 bits if 171 | such a type exists and the standard includes do not define it. */ 172 | #undef int32_t 173 | 174 | /* Define to the type of a signed integer type of width exactly 64 bits if 175 | such a type exists and the standard includes do not define it. */ 176 | #undef int64_t 177 | 178 | /* Define to rpl_malloc if the replacement function should be used. */ 179 | #undef malloc 180 | 181 | /* Define to `unsigned int' if does not define. */ 182 | #undef size_t 183 | 184 | /* Define to the type of an unsigned integer type of width exactly 64 bits if 185 | such a type exists and the standard includes do not define it. */ 186 | #undef uint64_t 187 | 188 | /* Define to the type of an unsigned integer type of width exactly 8 bits if 189 | such a type exists and the standard includes do not define it. */ 190 | #undef uint8_t 191 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # initial information about the project 2 | AC_PREREQ([2.67]) 3 | AC_INIT([luvi],[1.0],[michael@hinespot.com]) 4 | 5 | # check if the source folder is available 6 | AC_CONFIG_SRCDIR([common.c]) 7 | AC_CONFIG_HEADERS([config.h]) 8 | 9 | # automake initialization (mandatory) including a check for automake API version >= 1.9 10 | AM_INIT_AUTOMAKE([1.9]) 11 | AC_PROG_CC 12 | AC_PROG_MAKE_SET 13 | AC_PROG_INSTALL 14 | 15 | CFLAGS="$CFLAGS -I/usr/local/include" 16 | LDFLAGS="$LDFLAGS -L/usr/local/lib" 17 | CFLAGS="`echo $CXXFLAGS | sed -e 's|-O2||'`" 18 | 19 | AC_CHECK_PROG(PROTOBUF, protoc-c, protoc-c) 20 | 21 | if test x"$PROTOBUF" != x"protoc-c" ; then 22 | AC_MSG_ERROR([Google protocol buffers compiler is missing: apt-get install protobuf-c-compiler libprotobuf-c0-dev]) 23 | fi 24 | 25 | #AC_CHECK_LIB([protobuf-c], [protobuf_c_message_pack], [AC_MSG_RESULT([it works it works!!!!!!!!!!!!!])], [AC_MSG_ERROR([-lprotobuf-c missing: apt-get install protobuf-c-compiler libprotobuf-c0-dev])]) 26 | AC_CHECK_LIB([m], [floor], [], [AC_MSG_ERROR([-lm missing math libraries? what??])]) 27 | AC_CHECK_LIB([protobuf-c], [protobuf_c_message_pack],[], [AC_MSG_ERROR([-lprotobuf-c missing: apt-get install protobuf-c-compiler libprotobuf-c0-dev])]) 28 | AC_CHECK_LIB([xdo], [xdo_new], [], [AC_MSG_ERROR([-lxdo missing: apt-get install libxdo2 libxdo-dev])]) 29 | AC_CHECK_LIB([va], [vaCreateBuffer], [], [AC_MSG_ERROR([-lva missing: apt-get install libva1 libva-dev])]) 30 | AC_CHECK_LIB([bz2], [BZ2_bzDecompressInit], [], [AC_MSG_ERROR([-lbz2 missing: apt-get install libbz2-dev])]) 31 | AC_CHECK_LIB([x264], [x264_encoder_headers], [], [AC_MSG_ERROR([-lx264 missing: apt-get install libx264])]) 32 | AC_CHECK_LIB([pthread], [pthread_create], [], [AC_MSG_ERROR([-lpthread missing? wtf?])]) 33 | AC_CHECK_LIB([avutil], [av_log], [], [AC_MSG_ERROR([-lavutil missing: install ffmpeg/avconv libraries])]) 34 | AC_CHECK_LIB([avcodec], [av_log], [], [AC_MSG_ERROR([-lavcodec missing: install ffmpeg/avconv libraries])]) 35 | AC_CHECK_LIB([z], [inflate], [], [AC_MSG_ERROR([-lz missing? wtf?])]) 36 | AC_CHECK_LIB([avformat], [av_log], [], [AC_MSG_ERROR([-lavformat missing: install ffmpeg/avconv libraries])]) 37 | 38 | AC_CHECK_HEADERS([netdb.h], [], [AC_MSG_ERROR(["netdb.h: you don't have enough development headers"])]) 39 | AC_CHECK_HEADERS([sys/socket.h], [], [AC_MSG_ERROR(["sys/socket.h: you don't have enough development headers"])]) 40 | AC_CHECK_HEADERS([sys/types.h], [], [AC_MSG_ERROR(["sys/types.h: you don't have enough development headers"])]) 41 | AC_CHECK_HEADERS([netinet/in.h], [], [AC_MSG_ERROR(["arpa/inet.h: you don't have enough development headers"])]) 42 | AC_CHECK_HEADERS([arpa/inet.h], [], [AC_MSG_ERROR(["arpa/inet.h: you don't have enough development headers"])]) 43 | AC_CHECK_HEADERS([signal.h], [], [AC_MSG_ERROR(["signal.h: you don't have enough development headers"])]) 44 | AC_CHECK_HEADERS([stdio.h], [], [AC_MSG_ERROR(["stdio.h: you don't have enough development headers"])]) 45 | AC_CHECK_HEADERS([stdlib.h], [], [AC_MSG_ERROR(["stdlib.h: you don't have enough development headers"])]) 46 | AC_CHECK_HEADERS([string.h], [], [AC_MSG_ERROR(["string.h: you don't have enough development headers"])]) 47 | AC_CHECK_HEADERS([unistd.h], [], [AC_MSG_ERROR(["unistd.h: you don't have enough development headers"])]) 48 | AC_CHECK_HEADERS([pthread.h], [], [AC_MSG_ERROR(["pthread.h: you don't have enough development headers"])]) 49 | AC_CHECK_HEADERS([sys/time.h], [], [AC_MSG_ERROR(["sys/time.h: you don't have enough development headers"])]) 50 | AC_CHECK_HEADERS([fcntl.h], [], [AC_MSG_ERROR(["fcntl.h: you don't have enough development headers"])]) 51 | AC_CHECK_HEADERS([sys/mman.h], [], [AC_MSG_ERROR(["sys/mman.h: you don't have enough development headers"])]) 52 | AC_CHECK_HEADERS([assert.h], [], [AC_MSG_ERROR(["assert.h: you don't have enough development headers"])]) 53 | AC_CHECK_HEADERS([libavcodec/avcodec.h], [], [AC_MSG_ERROR([please install the ffmpeg/avconf libraries and headers])]) 54 | AC_CHECK_HEADERS([libavformat/avformat.h], [], [AC_MSG_ERROR([please install the ffmpeg/avconf libraries and headers])]) 55 | AC_CHECK_HEADERS([libavutil/opt.h], [], [AC_MSG_ERROR([please install the ffmpeg/avconf libraries and headers])]) 56 | AC_CHECK_HEADERS([libswscale/swscale.h], [], [AC_MSG_ERROR([please install the ffmpeg/avconf libraries and headers])]) 57 | AC_CHECK_HEADERS([X11/Xlib.h], [], [AC_MSG_ERROR([X11/Xlib.h missing: apt-get install libx11-dev])]) 58 | AC_CHECK_HEADERS([xdo.h], [], [AC_MSG_ERROR([xdo.h missing: apt-get install libxdo-dev])]) 59 | 60 | AC_CHECK_FUNCS([bzero gettimeofday inet_ntoa select socket], [], [AC_MSG_ERROR(["you don't have enough development headers"])]) 61 | 62 | AC_FUNC_MALLOC 63 | AC_TYPE_INT32_T 64 | AC_TYPE_INT64_T 65 | AC_TYPE_UINT64_T 66 | AC_TYPE_UINT8_T 67 | AC_TYPE_SIZE_T 68 | 69 | #files to generate via autotools (prepare .am or .in source files) 70 | AC_CONFIG_FILES([Makefile]) 71 | 72 | # finally this generates the Makefiles etc. for the build 73 | AC_OUTPUT 74 | 75 | -------------------------------------------------------------------------------- /install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # install - install a program, script, or datafile 3 | 4 | scriptversion=2011-01-19.21; # UTC 5 | 6 | # This originates from X11R5 (mit/util/scripts/install.sh), which was 7 | # later released in X11R6 (xc/config/util/install.sh) with the 8 | # following copyright and license. 9 | # 10 | # Copyright (C) 1994 X Consortium 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to 14 | # deal in the Software without restriction, including without limitation the 15 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 | # sell copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26 | # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27 | # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # Except as contained in this notice, the name of the X Consortium shall not 30 | # be used in advertising or otherwise to promote the sale, use or other deal- 31 | # ings in this Software without prior written authorization from the X Consor- 32 | # tium. 33 | # 34 | # 35 | # FSF changes to this file are in the public domain. 36 | # 37 | # Calling this script install-sh is preferred over install.sh, to prevent 38 | # `make' implicit rules from creating a file called install from it 39 | # when there is no Makefile. 40 | # 41 | # This script is compatible with the BSD install script, but was written 42 | # from scratch. 43 | 44 | nl=' 45 | ' 46 | IFS=" "" $nl" 47 | 48 | # set DOITPROG to echo to test this script 49 | 50 | # Don't use :- since 4.3BSD and earlier shells don't like it. 51 | doit=${DOITPROG-} 52 | if test -z "$doit"; then 53 | doit_exec=exec 54 | else 55 | doit_exec=$doit 56 | fi 57 | 58 | # Put in absolute file names if you don't have them in your path; 59 | # or use environment vars. 60 | 61 | chgrpprog=${CHGRPPROG-chgrp} 62 | chmodprog=${CHMODPROG-chmod} 63 | chownprog=${CHOWNPROG-chown} 64 | cmpprog=${CMPPROG-cmp} 65 | cpprog=${CPPROG-cp} 66 | mkdirprog=${MKDIRPROG-mkdir} 67 | mvprog=${MVPROG-mv} 68 | rmprog=${RMPROG-rm} 69 | stripprog=${STRIPPROG-strip} 70 | 71 | posix_glob='?' 72 | initialize_posix_glob=' 73 | test "$posix_glob" != "?" || { 74 | if (set -f) 2>/dev/null; then 75 | posix_glob= 76 | else 77 | posix_glob=: 78 | fi 79 | } 80 | ' 81 | 82 | posix_mkdir= 83 | 84 | # Desired mode of installed file. 85 | mode=0755 86 | 87 | chgrpcmd= 88 | chmodcmd=$chmodprog 89 | chowncmd= 90 | mvcmd=$mvprog 91 | rmcmd="$rmprog -f" 92 | stripcmd= 93 | 94 | src= 95 | dst= 96 | dir_arg= 97 | dst_arg= 98 | 99 | copy_on_change=false 100 | no_target_directory= 101 | 102 | usage="\ 103 | Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 104 | or: $0 [OPTION]... SRCFILES... DIRECTORY 105 | or: $0 [OPTION]... -t DIRECTORY SRCFILES... 106 | or: $0 [OPTION]... -d DIRECTORIES... 107 | 108 | In the 1st form, copy SRCFILE to DSTFILE. 109 | In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 110 | In the 4th, create DIRECTORIES. 111 | 112 | Options: 113 | --help display this help and exit. 114 | --version display version info and exit. 115 | 116 | -c (ignored) 117 | -C install only if different (preserve the last data modification time) 118 | -d create directories instead of installing files. 119 | -g GROUP $chgrpprog installed files to GROUP. 120 | -m MODE $chmodprog installed files to MODE. 121 | -o USER $chownprog installed files to USER. 122 | -s $stripprog installed files. 123 | -t DIRECTORY install into DIRECTORY. 124 | -T report an error if DSTFILE is a directory. 125 | 126 | Environment variables override the default commands: 127 | CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 128 | RMPROG STRIPPROG 129 | " 130 | 131 | while test $# -ne 0; do 132 | case $1 in 133 | -c) ;; 134 | 135 | -C) copy_on_change=true;; 136 | 137 | -d) dir_arg=true;; 138 | 139 | -g) chgrpcmd="$chgrpprog $2" 140 | shift;; 141 | 142 | --help) echo "$usage"; exit $?;; 143 | 144 | -m) mode=$2 145 | case $mode in 146 | *' '* | *' '* | *' 147 | '* | *'*'* | *'?'* | *'['*) 148 | echo "$0: invalid mode: $mode" >&2 149 | exit 1;; 150 | esac 151 | shift;; 152 | 153 | -o) chowncmd="$chownprog $2" 154 | shift;; 155 | 156 | -s) stripcmd=$stripprog;; 157 | 158 | -t) dst_arg=$2 159 | # Protect names problematic for `test' and other utilities. 160 | case $dst_arg in 161 | -* | [=\(\)!]) dst_arg=./$dst_arg;; 162 | esac 163 | shift;; 164 | 165 | -T) no_target_directory=true;; 166 | 167 | --version) echo "$0 $scriptversion"; exit $?;; 168 | 169 | --) shift 170 | break;; 171 | 172 | -*) echo "$0: invalid option: $1" >&2 173 | exit 1;; 174 | 175 | *) break;; 176 | esac 177 | shift 178 | done 179 | 180 | if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 181 | # When -d is used, all remaining arguments are directories to create. 182 | # When -t is used, the destination is already specified. 183 | # Otherwise, the last argument is the destination. Remove it from $@. 184 | for arg 185 | do 186 | if test -n "$dst_arg"; then 187 | # $@ is not empty: it contains at least $arg. 188 | set fnord "$@" "$dst_arg" 189 | shift # fnord 190 | fi 191 | shift # arg 192 | dst_arg=$arg 193 | # Protect names problematic for `test' and other utilities. 194 | case $dst_arg in 195 | -* | [=\(\)!]) dst_arg=./$dst_arg;; 196 | esac 197 | done 198 | fi 199 | 200 | if test $# -eq 0; then 201 | if test -z "$dir_arg"; then 202 | echo "$0: no input file specified." >&2 203 | exit 1 204 | fi 205 | # It's OK to call `install-sh -d' without argument. 206 | # This can happen when creating conditional directories. 207 | exit 0 208 | fi 209 | 210 | if test -z "$dir_arg"; then 211 | do_exit='(exit $ret); exit $ret' 212 | trap "ret=129; $do_exit" 1 213 | trap "ret=130; $do_exit" 2 214 | trap "ret=141; $do_exit" 13 215 | trap "ret=143; $do_exit" 15 216 | 217 | # Set umask so as not to create temps with too-generous modes. 218 | # However, 'strip' requires both read and write access to temps. 219 | case $mode in 220 | # Optimize common cases. 221 | *644) cp_umask=133;; 222 | *755) cp_umask=22;; 223 | 224 | *[0-7]) 225 | if test -z "$stripcmd"; then 226 | u_plus_rw= 227 | else 228 | u_plus_rw='% 200' 229 | fi 230 | cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 231 | *) 232 | if test -z "$stripcmd"; then 233 | u_plus_rw= 234 | else 235 | u_plus_rw=,u+rw 236 | fi 237 | cp_umask=$mode$u_plus_rw;; 238 | esac 239 | fi 240 | 241 | for src 242 | do 243 | # Protect names problematic for `test' and other utilities. 244 | case $src in 245 | -* | [=\(\)!]) src=./$src;; 246 | esac 247 | 248 | if test -n "$dir_arg"; then 249 | dst=$src 250 | dstdir=$dst 251 | test -d "$dstdir" 252 | dstdir_status=$? 253 | else 254 | 255 | # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 256 | # might cause directories to be created, which would be especially bad 257 | # if $src (and thus $dsttmp) contains '*'. 258 | if test ! -f "$src" && test ! -d "$src"; then 259 | echo "$0: $src does not exist." >&2 260 | exit 1 261 | fi 262 | 263 | if test -z "$dst_arg"; then 264 | echo "$0: no destination specified." >&2 265 | exit 1 266 | fi 267 | dst=$dst_arg 268 | 269 | # If destination is a directory, append the input filename; won't work 270 | # if double slashes aren't ignored. 271 | if test -d "$dst"; then 272 | if test -n "$no_target_directory"; then 273 | echo "$0: $dst_arg: Is a directory" >&2 274 | exit 1 275 | fi 276 | dstdir=$dst 277 | dst=$dstdir/`basename "$src"` 278 | dstdir_status=0 279 | else 280 | # Prefer dirname, but fall back on a substitute if dirname fails. 281 | dstdir=` 282 | (dirname "$dst") 2>/dev/null || 283 | expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 284 | X"$dst" : 'X\(//\)[^/]' \| \ 285 | X"$dst" : 'X\(//\)$' \| \ 286 | X"$dst" : 'X\(/\)' \| . 2>/dev/null || 287 | echo X"$dst" | 288 | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 289 | s//\1/ 290 | q 291 | } 292 | /^X\(\/\/\)[^/].*/{ 293 | s//\1/ 294 | q 295 | } 296 | /^X\(\/\/\)$/{ 297 | s//\1/ 298 | q 299 | } 300 | /^X\(\/\).*/{ 301 | s//\1/ 302 | q 303 | } 304 | s/.*/./; q' 305 | ` 306 | 307 | test -d "$dstdir" 308 | dstdir_status=$? 309 | fi 310 | fi 311 | 312 | obsolete_mkdir_used=false 313 | 314 | if test $dstdir_status != 0; then 315 | case $posix_mkdir in 316 | '') 317 | # Create intermediate dirs using mode 755 as modified by the umask. 318 | # This is like FreeBSD 'install' as of 1997-10-28. 319 | umask=`umask` 320 | case $stripcmd.$umask in 321 | # Optimize common cases. 322 | *[2367][2367]) mkdir_umask=$umask;; 323 | .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 324 | 325 | *[0-7]) 326 | mkdir_umask=`expr $umask + 22 \ 327 | - $umask % 100 % 40 + $umask % 20 \ 328 | - $umask % 10 % 4 + $umask % 2 329 | `;; 330 | *) mkdir_umask=$umask,go-w;; 331 | esac 332 | 333 | # With -d, create the new directory with the user-specified mode. 334 | # Otherwise, rely on $mkdir_umask. 335 | if test -n "$dir_arg"; then 336 | mkdir_mode=-m$mode 337 | else 338 | mkdir_mode= 339 | fi 340 | 341 | posix_mkdir=false 342 | case $umask in 343 | *[123567][0-7][0-7]) 344 | # POSIX mkdir -p sets u+wx bits regardless of umask, which 345 | # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 346 | ;; 347 | *) 348 | tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 349 | trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 350 | 351 | if (umask $mkdir_umask && 352 | exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 353 | then 354 | if test -z "$dir_arg" || { 355 | # Check for POSIX incompatibilities with -m. 356 | # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 357 | # other-writeable bit of parent directory when it shouldn't. 358 | # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 359 | ls_ld_tmpdir=`ls -ld "$tmpdir"` 360 | case $ls_ld_tmpdir in 361 | d????-?r-*) different_mode=700;; 362 | d????-?--*) different_mode=755;; 363 | *) false;; 364 | esac && 365 | $mkdirprog -m$different_mode -p -- "$tmpdir" && { 366 | ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 367 | test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 368 | } 369 | } 370 | then posix_mkdir=: 371 | fi 372 | rmdir "$tmpdir/d" "$tmpdir" 373 | else 374 | # Remove any dirs left behind by ancient mkdir implementations. 375 | rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 376 | fi 377 | trap '' 0;; 378 | esac;; 379 | esac 380 | 381 | if 382 | $posix_mkdir && ( 383 | umask $mkdir_umask && 384 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 385 | ) 386 | then : 387 | else 388 | 389 | # The umask is ridiculous, or mkdir does not conform to POSIX, 390 | # or it failed possibly due to a race condition. Create the 391 | # directory the slow way, step by step, checking for races as we go. 392 | 393 | case $dstdir in 394 | /*) prefix='/';; 395 | [-=\(\)!]*) prefix='./';; 396 | *) prefix='';; 397 | esac 398 | 399 | eval "$initialize_posix_glob" 400 | 401 | oIFS=$IFS 402 | IFS=/ 403 | $posix_glob set -f 404 | set fnord $dstdir 405 | shift 406 | $posix_glob set +f 407 | IFS=$oIFS 408 | 409 | prefixes= 410 | 411 | for d 412 | do 413 | test X"$d" = X && continue 414 | 415 | prefix=$prefix$d 416 | if test -d "$prefix"; then 417 | prefixes= 418 | else 419 | if $posix_mkdir; then 420 | (umask=$mkdir_umask && 421 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 422 | # Don't fail if two instances are running concurrently. 423 | test -d "$prefix" || exit 1 424 | else 425 | case $prefix in 426 | *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 427 | *) qprefix=$prefix;; 428 | esac 429 | prefixes="$prefixes '$qprefix'" 430 | fi 431 | fi 432 | prefix=$prefix/ 433 | done 434 | 435 | if test -n "$prefixes"; then 436 | # Don't fail if two instances are running concurrently. 437 | (umask $mkdir_umask && 438 | eval "\$doit_exec \$mkdirprog $prefixes") || 439 | test -d "$dstdir" || exit 1 440 | obsolete_mkdir_used=true 441 | fi 442 | fi 443 | fi 444 | 445 | if test -n "$dir_arg"; then 446 | { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 447 | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 448 | { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 449 | test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 450 | else 451 | 452 | # Make a couple of temp file names in the proper directory. 453 | dsttmp=$dstdir/_inst.$$_ 454 | rmtmp=$dstdir/_rm.$$_ 455 | 456 | # Trap to clean up those temp files at exit. 457 | trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 458 | 459 | # Copy the file name to the temp name. 460 | (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 461 | 462 | # and set any options; do chmod last to preserve setuid bits. 463 | # 464 | # If any of these fail, we abort the whole thing. If we want to 465 | # ignore errors from any of these, just make sure not to ignore 466 | # errors from the above "$doit $cpprog $src $dsttmp" command. 467 | # 468 | { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 469 | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 470 | { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 471 | { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 472 | 473 | # If -C, don't bother to copy if it wouldn't change the file. 474 | if $copy_on_change && 475 | old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 476 | new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 477 | 478 | eval "$initialize_posix_glob" && 479 | $posix_glob set -f && 480 | set X $old && old=:$2:$4:$5:$6 && 481 | set X $new && new=:$2:$4:$5:$6 && 482 | $posix_glob set +f && 483 | 484 | test "$old" = "$new" && 485 | $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 486 | then 487 | rm -f "$dsttmp" 488 | else 489 | # Rename the file to the real destination. 490 | $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 491 | 492 | # The rename failed, perhaps because mv can't rename something else 493 | # to itself, or perhaps because mv is so ancient that it does not 494 | # support -f. 495 | { 496 | # Now remove or move aside any old file at destination location. 497 | # We try this two ways since rm can't unlink itself on some 498 | # systems and the destination file might be busy for other 499 | # reasons. In this case, the final cleanup might fail but the new 500 | # file should still install successfully. 501 | { 502 | test ! -f "$dst" || 503 | $doit $rmcmd -f "$dst" 2>/dev/null || 504 | { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 505 | { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 506 | } || 507 | { echo "$0: cannot unlink or rename $dst" >&2 508 | (exit 1); exit 1 509 | } 510 | } && 511 | 512 | # Now rename the file to the real destination. 513 | $doit $mvcmd "$dsttmp" "$dst" 514 | } 515 | fi || exit 1 516 | 517 | trap '' 0 518 | fi 519 | done 520 | 521 | # Local variables: 522 | # eval: (add-hook 'write-file-hooks 'time-stamp) 523 | # time-stamp-start: "scriptversion=" 524 | # time-stamp-format: "%:y-%02m-%02d.%02H" 525 | # time-stamp-time-zone: "UTC" 526 | # time-stamp-end: "; # UTC" 527 | # End: 528 | -------------------------------------------------------------------------------- /luvi.h: -------------------------------------------------------------------------------- 1 | #ifndef FARM_H 2 | #define FARM_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | //#define NDEBUG 23 | #include 24 | #include "luvi.pb-c.h" 25 | 26 | #define USEC(x) (ulong) (x.tv_sec * 1000000 + x.tv_usec) 27 | 28 | /* 29 | * These contansts are totally empirical, and should probably include 30 | * some code in the future for dynamic adjustability. 31 | */ 32 | 33 | #define MAX_SLAVES 10 // arbitrary, can be increased 34 | #define MAX_PACKET 1000000 // maximum I-frame byte size 35 | #define MAX_DUPS 10 // maximum duplicated packets between timebases 36 | #define QUEUESIZE 4000 // maximum outstanding I/O to slaves 37 | #define RANGESIZE 10 // maximum GOPs per slave to transcode (Range) 38 | #define MAX_EXPECTED_GOP_SIZE 300 // maximum frames per GOP 39 | #define MAX_STAGING 32*1024*1024 // not used 40 | #define NETWORK_BUFFER 1000000 // setsockopt buffer size 41 | #define MAX_MSG_SIZE 4096 // maximum protocol buffer size 42 | 43 | // I'm not using encode_video2(), yet. Stop yelling at me. 44 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 45 | 46 | static AVRational myAVTIMEBASEQ = {1, AV_TIME_BASE}; 47 | static int debug = 3; 48 | 49 | typedef enum { 50 | INIT = 0, 51 | CODEC = 1, 52 | TRANSCODE = 2, 53 | TRANSCODE_RESULT = 3, 54 | CMDLEN = 4, 55 | } command_code_t; 56 | 57 | static char * describe[] = { 58 | "initialize", 59 | "codec", 60 | "transcode", 61 | "transcode_result", 62 | }; 63 | 64 | typedef struct QUEUE queue; 65 | 66 | /* 67 | * Data structures for slave workers. 68 | */ 69 | typedef struct { 70 | int fd; 71 | int id; 72 | int ranges; 73 | int busy; 74 | queue * results; 75 | char ip[30]; 76 | char name[100]; uint8_t sbuf[MAX_MSG_SIZE]; 77 | uint8_t rbuf[MAX_MSG_SIZE]; 78 | } slave_t; 79 | 80 | /* 81 | * Each queue entry represents the transcoding 82 | * of a single video frame. 83 | */ 84 | typedef struct { 85 | /* 86 | * Pre-caculated timing parameters of this frame sent to the slaves. 87 | */ 88 | int got_packet; 89 | int fd; 90 | int type; 91 | float inPts; 92 | float outFrames; 93 | float vdelta; 94 | int64_t m_pts; 95 | int32_t current_frame_number; 96 | 97 | /* 98 | * The resulting meta-data of the transcoded frame, 99 | * including any duplicate frames that may result. 100 | */ 101 | int64_t pts[MAX_DUPS]; 102 | int64_t dts[MAX_DUPS]; 103 | int32_t flags[MAX_DUPS]; 104 | int32_t buffer_lengths[MAX_DUPS]; 105 | 106 | /* 107 | * Temporary variables used during transcoding. 108 | */ 109 | AVPacket save_packet; 110 | Packet packet; 111 | uint8_t * outBuffers[MAX_DUPS]; 112 | 113 | /* 114 | * Structures used for communicating with slaves workers. 115 | */ 116 | Config configuration; 117 | Convert convert; 118 | Command cmd; 119 | Values values; 120 | Command * recv; 121 | slave_t * slave; 122 | } queue_entry_t; 123 | 124 | #define ENTRYSIZE sizeof(queue_entry_t) 125 | 126 | /* 127 | * Multi-threaded producer/consumer. 128 | */ 129 | struct QUEUE { 130 | queue_entry_t ** cmds; 131 | long head, 132 | tail; 133 | int full, 134 | empty; 135 | pthread_mutex_t * mut; 136 | pthread_cond_t * notFull, 137 | * notEmpty; 138 | int max; 139 | int size; 140 | }; 141 | 142 | /* 143 | * Private variables used for FFMPEG interactions, 144 | * including slave management, codec management, 145 | */ 146 | typedef struct { 147 | Config configuration; 148 | pthread_t in_consumer; 149 | pthread_t out_consumer; 150 | pthread_t listener; 151 | int64_t start_time; 152 | int processors; 153 | int audioStream; 154 | int videoStream; 155 | int stop_in_consumer; 156 | int stop_out_consumer; 157 | int stop_listener; 158 | int ready_for_slaves; 159 | int drops_stopped; 160 | int encoder_clean; 161 | int first_keyframe_reached; 162 | int remote; 163 | int sockd; 164 | int stagefd; 165 | void * staging; 166 | int num_slaves; 167 | int ranges; 168 | double fps; 169 | char hostname[100]; 170 | xdo_t * xdo; 171 | slave_t slaves[MAX_SLAVES]; 172 | slave_t * curr_slave; 173 | queue * in_fifo; 174 | queue * out_fifo; 175 | AVFormatContext * inFormatCtx; 176 | AVFormatContext * outFormatCtx; 177 | AVCodecContext * outVideoCodecCtx; 178 | AVCodecContext * inVideoCodecCtx; 179 | AVCodecContext * outAudioCodecCtx; 180 | AVCodecContext * inAudioCodecCtx; 181 | AVCodec * outVideoCodec; 182 | AVCodec * inVideoCodec; 183 | AVCodec * outAudioCodec; 184 | AVCodec * inAudioCodec; 185 | AVFrame * outVideoFrame; 186 | AVFrame * inVideoFrame; 187 | AVStream * inVideoStream; 188 | AVStream * inAudioStream; 189 | AVStream * outVideoStream; 190 | AVStream * outAudioStream; 191 | AVPacket inPacket; 192 | AVPicture outPicture; 193 | } Context; 194 | 195 | /* 196 | * FFMPEG initializtion routines, 197 | * for both the input codec and the 198 | * output codecs. 199 | */ 200 | int init_ctx(Context * ctx, int queuesize); 201 | int init_in(Context * ctx, int slave); 202 | int init_out(Context * ctx, int slave); 203 | void init_codec(Context * ctx, AVCodecContext * outVideoCodecCtx, int slave); 204 | void destroy_ctx_in(Context * ctx); 205 | void destroy_ctx_out(Context * ctx); 206 | void destroy_ctx(Context * ctx); 207 | 208 | /* 209 | * Actual transcoding routines 210 | */ 211 | int transcode(Context * ctx, queue_entry_t * e, Convert * convert, AVPacket * packet); 212 | void packet_to_protobuf(Packet * dest, AVPacket * src); 213 | void protobuf_to_packet(AVPacket * dest, Packet * src); 214 | void store_transcode_result(Command * send, queue_entry_t * e); 215 | 216 | /* 217 | * Networking helper functions for non-blocking sockets 218 | * and management of protocol with slaves. 219 | */ 220 | int cmdsend(int fd, void * buf, Command * cmd); 221 | int cmdrecv(int fd, void * buf, Command ** cmd, int32_t expecting); 222 | int multirecv(int fd, uint8_t * buffer, int size); 223 | int multiwrite(int fd, uint8_t * packet_data, int remaining); 224 | 225 | /* 226 | * FIFO queue management. 227 | */ 228 | queue * queueInit (int queuesize); 229 | void queueDelete (queue *q); 230 | void queueAdd (queue *q, queue_entry_t * in); 231 | void queueDel (queue *q, queue_entry_t **out); 232 | void push(queue * fifo, queue_entry_t * e); 233 | queue_entry_t * pop(queue * fifo, int * stop); 234 | queue_entry_t * queueHead(queue *q); 235 | void in_consumer_stop(Context * ctx); 236 | void out_consumer_stop(Context * ctx); 237 | 238 | struct addrinfo * gethost(char * name); 239 | void update_fps(Context * ctx, int init); 240 | 241 | #endif 242 | -------------------------------------------------------------------------------- /luvi.proto: -------------------------------------------------------------------------------- 1 | message Config 2 | { 3 | required int32 video_codec_id=1; 4 | required int32 video_bit_rate=2; 5 | required int32 width=3; 6 | required int32 height=4; 7 | required int32 frame_number=5; 8 | required float avg_framerate=6; 9 | required float expected_total_frames=7; 10 | required int32 avg_frame_rate_num=8; 11 | required int32 avg_frame_rate_den=9; 12 | required int32 sample_aspect_ratio_num=10; 13 | required int32 sample_aspect_ratio_den=11; 14 | required int32 stream_time_base_num=12; 15 | required int32 stream_time_base_den=13; 16 | required int32 audio_codec_id=14; 17 | required int32 audio_sample_rate=15; 18 | required int32 audio_sample_format=16; 19 | required int32 audio_channels=17; 20 | required int32 audio_bit_rate=18; 21 | required int32 audio_frame_size=19; 22 | required int32 audio_service_type=20; 23 | required int32 audio_block_align=21; 24 | } 25 | 26 | message Packet 27 | { 28 | required int64 pts=1; 29 | required int64 dts=2; 30 | required int32 size=3; 31 | required int32 stream_index=4; 32 | required int32 flags=5; 33 | required int32 duration=6; 34 | required int64 pos=7; 35 | required int64 convergence_duration=8; 36 | } 37 | 38 | message Values 39 | { 40 | repeated int32 buffer_lengths=1; 41 | repeated int64 pts=2; 42 | repeated int64 dts=3; 43 | repeated int32 flags=4; 44 | } 45 | 46 | message Convert { 47 | required int32 do_not_reply=1; 48 | required int32 finished=2; 49 | required int32 n_frame_count=3; 50 | required int32 extra_frame_count=4; 51 | required int32 buffers=5; 52 | required int32 frame_number=6; 53 | optional Packet packet=8; 54 | optional Values values=7; 55 | } 56 | 57 | message Command { 58 | required int32 code=1; 59 | optional Convert convert=2; 60 | optional Config configuration=3; 61 | optional string name = 4; 62 | } 63 | -------------------------------------------------------------------------------- /master.c: -------------------------------------------------------------------------------- 1 | #include "luvi.h" 2 | 3 | int abort_requested = 0; 4 | 5 | static void my_handler(int s) 6 | { 7 | printf("\nAbort requested (CTRL-C)\n"); 8 | if(abort_requested) { 9 | printf("Abort didn't work. Bailing\n"); 10 | exit(1); 11 | } 12 | abort_requested = 1; 13 | } 14 | 15 | 16 | static void my_write_packet(Context * ctx, AVPacket * pkt) 17 | { 18 | // if(av_interleaved_write_frame(ctx->outFormatCtx, pkt) < 0) { 19 | if(av_write_frame(ctx->outFormatCtx, pkt) < 0) { 20 | printf("Could not output packet\n"); 21 | exit(1); 22 | } 23 | // avio_flush(ctx->outFormatCtx->pb); 24 | } 25 | 26 | static void output_audio(Context * ctx, queue_entry_t * e) 27 | { 28 | 29 | if(debug==4 || debug == 2) 30 | printf("Got audio packet @ pts %" PRId64 " dts %" PRId64 "\n", ctx->inPacket.pts, ctx->inPacket.dts); 31 | 32 | e->save_packet.stream_index = ctx->outAudioStream->index; 33 | e->save_packet.pts -= ctx->start_time; 34 | e->save_packet.dts = e->save_packet.pts; 35 | 36 | if(e->save_packet.pts >= 0) { 37 | if(debug==4 || debug == 2) 38 | printf("MUXAudio: Writing audio frame with PTS: %" PRId64 "\n", e->save_packet.pts); 39 | my_write_packet(ctx, &e->save_packet); 40 | 41 | } else { 42 | if(debug==4 || debug == 2) 43 | printf("MUXAudio: Dropping audio frame with PTS: %" PRId64 "\n", e->save_packet.pts); 44 | } 45 | av_free_packet(&e->save_packet); 46 | } 47 | 48 | static void output_video(Context * ctx, queue_entry_t * e, Command * cmd) 49 | { 50 | int x; 51 | AVPacket outpkt; 52 | 53 | if(cmd->convert->buffers > 0) { 54 | if(debug==2) 55 | printf("dts/m_pts %" PRId64 " vdelta %f buffers %d\n", e->m_pts, e->vdelta, cmd->convert->buffers); 56 | 57 | for(x = 0; x < cmd->convert->buffers; x++) { 58 | av_init_packet(&outpkt); 59 | 60 | outpkt.data = e->outBuffers[x]; 61 | outpkt.size = cmd->convert->values->buffer_lengths[x]; 62 | outpkt.pts = cmd->convert->values->pts[x]; 63 | outpkt.dts = cmd->convert->values->dts[x]; 64 | outpkt.flags = cmd->convert->values->flags[x]; 65 | 66 | if(ctx->remote && (debug==2 || (ctx->in_fifo->size % 40) == 0)) { 67 | printf("(%d %%) (%d) Writing from slave %d (%s), ranges %d size %d frame %d total ranges %d queue %d fps %f =======\n", 68 | (int) (((double) ctx->configuration.frame_number / (double) ctx->configuration.expected_total_frames) * 100), 69 | ctx->configuration.frame_number, 70 | e->slave ? e->slave->id : -1, 71 | e->slave ? e->slave->name : "n/a", 72 | e->slave ? e->slave->ranges : -1, 73 | outpkt.size, 74 | ctx->configuration.frame_number, 75 | ctx->ranges, 76 | ctx->in_fifo->size, 77 | ctx->fps); 78 | 79 | if(debug==2) 80 | printf("\n"); 81 | else 82 | fflush(stdout); 83 | } 84 | 85 | my_write_packet(ctx, &outpkt); 86 | av_free(e->outBuffers[x]); 87 | } 88 | } 89 | } 90 | 91 | static void setnonblocking(int sock) 92 | { 93 | int opts; 94 | 95 | opts = fcntl(sock,F_GETFL); 96 | if (opts < 0) { 97 | perror("fcntl(F_GETFL)"); 98 | exit(EXIT_FAILURE); 99 | } 100 | opts = (opts | O_NONBLOCK); 101 | if (fcntl(sock,F_SETFL,opts) < 0) { 102 | perror("fcntl(F_SETFL)"); 103 | exit(EXIT_FAILURE); 104 | } 105 | } 106 | 107 | static int my_select(Context * ctx, fd_set * socks, int read) 108 | { 109 | int highest = 0, x, y, check_only = 1, ready; 110 | struct timeval timeout; 111 | 112 | highest = 0; 113 | FD_ZERO(socks); 114 | 115 | for(x = 0; x < ctx->num_slaves; x++) { 116 | int fd = ctx->slaves[x].fd; 117 | if(fd > highest) 118 | highest = fd; 119 | FD_SET(fd, socks); 120 | } 121 | 122 | timeout.tv_sec = 2; 123 | timeout.tv_usec = 0; 124 | 125 | if(read) 126 | ready = select(highest + 1, socks, NULL, NULL, &timeout); 127 | else 128 | ready = select(highest + 1, NULL, socks, NULL, &timeout); 129 | 130 | if (ready < 0) { 131 | if(read) 132 | perror("select read"); 133 | else 134 | perror("select write"); 135 | exit(1); 136 | } 137 | 138 | return ready; 139 | } 140 | 141 | static void * disk_writer (void * opaque) 142 | { 143 | queue_entry_t * e = NULL; 144 | Context * ctx = opaque; 145 | int x, y, check_only = 1; 146 | fd_set socks; 147 | int ready; 148 | 149 | while(abort_requested == 0) { 150 | /* Are we still waiting for the head? */ 151 | if(!e) { 152 | /* No? Get the next one */ 153 | if(!(e = pop(ctx->in_fifo, &ctx->stop_in_consumer))) 154 | break; 155 | } 156 | 157 | if(e->type == ctx->audioStream) { 158 | output_audio(ctx, e); 159 | free(e); 160 | e = NULL; 161 | continue; 162 | } 163 | 164 | if(!ctx->remote || !ctx->ready_for_slaves) { 165 | output_video(ctx, e, &e->cmd); 166 | free(e); 167 | e = NULL; 168 | continue; 169 | } 170 | 171 | do { 172 | ready = my_select(ctx, &socks, 1); 173 | if(!ready) 174 | printf("Timeout.\n"); 175 | } while(e == NULL && ready == 0 && abort_requested == 0); 176 | 177 | if(ready) { 178 | for(y = 0; y < ctx->num_slaves; y++) { 179 | slave_t * slave = &ctx->slaves[y]; 180 | queue_entry_t * data; 181 | int fd = slave->fd; 182 | 183 | if(!FD_ISSET(fd, &socks)) 184 | continue; 185 | 186 | if(slave->results->size == (slave->results->max - 1)) 187 | continue; 188 | 189 | data = malloc(ENTRYSIZE); 190 | assert(data); 191 | cmdrecv(fd, slave->rbuf, &data->recv, TRANSCODE_RESULT); 192 | data->slave = slave; 193 | data->type = ctx->videoStream; 194 | 195 | for(x = 0; x < data->recv->convert->buffers; x++) { 196 | if(debug==2) 197 | printf("Receiving %d bytes for slave %d\n", data->recv->convert->values->buffer_lengths[x], slave->id); 198 | data->outBuffers[x] = av_malloc(data->recv->convert->values->buffer_lengths[x]); 199 | assert(data->outBuffers[x]); 200 | if(multirecv(fd, data->outBuffers[x], data->recv->convert->values->buffer_lengths[x]) <= 0) { 201 | printf("Could not receive %d bytes for slave %d\n", data->recv->convert->values->buffer_lengths[x], slave->id); 202 | exit(1); 203 | } 204 | } 205 | 206 | push(slave->results, data); 207 | slave->busy--; 208 | update_fps(ctx, 0); 209 | } 210 | } else 211 | printf("Timeout, checking queues: %p\n", e); 212 | 213 | ready = 0; 214 | 215 | /* 216 | * Check to see if the head matches any of the 217 | * data being currently held. 218 | */ 219 | for(y = 0; y < ctx->num_slaves; y++) { 220 | slave_t * slave = &ctx->slaves[y]; 221 | queue_entry_t * head = queueHead(slave->results); 222 | 223 | if(!head) 224 | continue; 225 | 226 | if(head->type != ctx->videoStream) 227 | continue; 228 | 229 | if(head->recv->convert->frame_number != e->cmd.convert->frame_number) 230 | continue; 231 | 232 | head = pop(slave->results, &check_only); 233 | output_video(ctx, head, head->recv); 234 | command__free_unpacked(head->recv, NULL); 235 | free(head); 236 | free(e); 237 | y = -1; 238 | do { 239 | if(!(e = pop(ctx->in_fifo, &check_only))) 240 | break; 241 | if(e->type == ctx->audioStream) { 242 | output_audio(ctx, e); 243 | free(e); 244 | e = NULL; 245 | continue; 246 | } 247 | break; 248 | } while(1); 249 | } 250 | 251 | } 252 | return NULL; 253 | } 254 | 255 | void *slave_listener(void * opaque) 256 | { 257 | Context * ctx = opaque; 258 | Command cmd; 259 | int newsockd, size, got; 260 | struct sockaddr_in saddr; 261 | int sendbuff = NETWORK_BUFFER, rcvbuff = NETWORK_BUFFER, res; 262 | 263 | size = sizeof(saddr); 264 | 265 | while(!ctx->stop_listener) { 266 | Command * recv = NULL; 267 | slave_t * slave; 268 | printf("== accept\n"); 269 | if((newsockd = accept(ctx->sockd, (struct sockaddr *) &saddr, &size)) < 0) { 270 | if(ctx->stop_listener) { 271 | printf("Listener exiting now.\n"); 272 | break; 273 | } 274 | perror("accept error"); 275 | exit(1); 276 | } 277 | 278 | res = setsockopt(newsockd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)); 279 | 280 | if(res < 0) { 281 | perror("setsockopt: send buffer:"); 282 | printf("Failed to increase new slave's send buffer\n"); 283 | exit(1); 284 | } 285 | 286 | res = setsockopt(newsockd, SOL_SOCKET, SO_RCVBUF, &rcvbuff, sizeof(rcvbuff)); 287 | 288 | if(res < 0) { 289 | perror("setsockopt: receive buffer:"); 290 | printf("Failed to increase new slave's recieve buffer\n"); 291 | exit(1); 292 | } 293 | 294 | printf("== accepted with fd %d, buffer: %d %d\n", newsockd, sendbuff, rcvbuff); 295 | 296 | slave = &(ctx->slaves[ctx->num_slaves]); 297 | got = cmdrecv(newsockd, slave->rbuf, &recv, INIT); 298 | strcpy(slave->name, recv->name); 299 | command__free_unpacked(recv, NULL); 300 | 301 | printf("Sending codec id %d\n", ctx->configuration.video_codec_id); 302 | 303 | command__init(&cmd); 304 | cmd.configuration = &ctx->configuration; 305 | cmd.code = CODEC; 306 | got = cmdsend(newsockd, slave->sbuf, &cmd); 307 | strcpy(slave->ip, inet_ntoa(saddr.sin_addr)); 308 | slave->fd = newsockd; 309 | slave->id = ctx->num_slaves; 310 | ctx->num_slaves++; 311 | printf("stored fd: %d\n", slave->fd); 312 | setnonblocking(newsockd); 313 | } 314 | return NULL; 315 | } 316 | 317 | int main(int argc, char *argv[]) { 318 | Context * ctx; 319 | queue_entry_t gop_entries[MAX_EXPECTED_GOP_SIZE]; 320 | struct sockaddr_in raddr; 321 | int64_t m_ptsOffset; 322 | int got, 323 | numBytes, 324 | on = 1, 325 | got_output, 326 | x, 327 | y, 328 | rport, 329 | total_packets = 0, 330 | key_frames = 0, 331 | icount = 0, 332 | gop_length = 0, 333 | flags; 334 | char action_character; 335 | fd_set socks; 336 | 337 | struct sigaction sigIntHandler; 338 | 339 | sigIntHandler.sa_handler = my_handler; 340 | sigemptyset(&sigIntHandler.sa_mask); 341 | sigIntHandler.sa_flags = 0; 342 | sigaction(SIGINT, &sigIntHandler, NULL); 343 | 344 | if(argc < 5) { 345 | printf("usage: [infile] [outfile] [port] [remote] [slave transcode 0|1]\n"); 346 | return -1; 347 | } 348 | 349 | ctx = malloc(sizeof(Context)); 350 | rport = atoi(argv[3]); 351 | ctx->remote = atoi(argv[4]); 352 | 353 | if(init_ctx(ctx, 20000) < 0) 354 | return -1; 355 | 356 | if(ctx->remote) { 357 | if ((ctx->sockd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 358 | perror("socket"); 359 | return -1; 360 | } 361 | 362 | bzero(&raddr, sizeof(raddr)); 363 | raddr.sin_family = AF_INET; 364 | raddr.sin_addr.s_addr = htonl(INADDR_ANY); 365 | raddr.sin_port = htons(rport); /* daytime server */ 366 | 367 | if (setsockopt(ctx->sockd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { 368 | perror("setsockopt(SO_REUSEADDR)"); 369 | return -1; 370 | } 371 | 372 | if(bind(ctx->sockd, (struct sockaddr *)(&raddr), sizeof(raddr)) < 0) { 373 | perror("bind"); 374 | return -1; 375 | } 376 | 377 | printf("== listen\n"); 378 | if(listen(ctx->sockd, MAX_SLAVES) < 0) { 379 | perror("listen"); 380 | return -1; 381 | } 382 | 383 | printf("== listening\n"); 384 | 385 | pthread_create (&ctx->listener, NULL, slave_listener, ctx); 386 | } 387 | 388 | // Open video file 389 | printf("Opening source: %s\n", argv[1]); 390 | if(avformat_open_input(&ctx->inFormatCtx, argv[1], NULL, NULL) != 0) { 391 | perror("avformat_open_input"); 392 | printf("Could not open source video file.\n"); 393 | return -1; 394 | } 395 | 396 | // Retrieve stream information 397 | if(avformat_find_stream_info(ctx->inFormatCtx, NULL) < 0) { 398 | perror("avformat_find_stream_info"); 399 | printf("Could not find stream information\n"); 400 | return -1; 401 | } 402 | 403 | for(x = 0; x < ctx->inFormatCtx->nb_streams; x++) { 404 | if(ctx->inFormatCtx->streams[x]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { 405 | if(ctx->videoStream == -1) { 406 | ctx->videoStream = x; 407 | ctx->inVideoStream = ctx->inFormatCtx->streams[x]; 408 | ctx->configuration.video_codec_id = ctx->inFormatCtx->streams[x]->codec->codec_id; 409 | printf("Found first video stream\n"); 410 | } else 411 | printf("Ignoring extra video stream %d\n", x); 412 | } else if(ctx->inFormatCtx->streams[x]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { 413 | if(ctx->audioStream == -1) { 414 | 415 | ctx->audioStream = x; 416 | ctx->inAudioStream = ctx->inFormatCtx->streams[x]; 417 | ctx->configuration.audio_codec_id = ctx->inAudioStream->codec->codec_id; 418 | printf("Found first audio stream\n"); 419 | } else 420 | printf("Ignoring extra audio stream %d\n", x); 421 | } else { 422 | printf("Ignoring unknown stream %d\n", x); 423 | } 424 | } 425 | 426 | if(ctx->videoStream == -1) { 427 | printf("No video streams found.\n"); 428 | return -1; 429 | } 430 | 431 | if(ctx->audioStream == -1) { 432 | printf("No audio streams found.\n"); 433 | ctx->configuration.audio_codec_id = -1; 434 | } 435 | 436 | if(init_in(ctx, 0) < 0) 437 | return -1; 438 | 439 | ctx->configuration.video_bit_rate = ctx->inFormatCtx->bit_rate; 440 | ctx->configuration.width = ctx->inVideoStream->codec->width; 441 | ctx->configuration.height = ctx->inVideoStream->codec->height; 442 | ctx->configuration.avg_frame_rate_num = ctx->inVideoStream->avg_frame_rate.num; 443 | ctx->configuration.avg_frame_rate_den = ctx->inVideoStream->avg_frame_rate.den; 444 | ctx->configuration.sample_aspect_ratio_num = ctx->inVideoStream->codec->sample_aspect_ratio.num; 445 | ctx->configuration.sample_aspect_ratio_den = ctx->inVideoStream->codec->sample_aspect_ratio.den; 446 | ctx->configuration.avg_framerate = (float)ctx->configuration.avg_frame_rate_num / (float)ctx->configuration.avg_frame_rate_den; 447 | ctx->configuration.expected_total_frames = ctx->configuration.avg_framerate * (ctx->inFormatCtx->duration / AV_TIME_BASE); 448 | ctx->configuration.stream_time_base_num = ctx->inVideoStream->time_base.num; 449 | ctx->configuration.stream_time_base_den = ctx->inVideoStream->time_base.den; 450 | 451 | if(ctx->audioStream != -1) { 452 | ctx->configuration.audio_sample_rate = ctx->inAudioStream->codec->sample_rate; 453 | ctx->configuration.audio_sample_format = ctx->inAudioStream->codec->sample_fmt; 454 | ctx->configuration.audio_bit_rate = ctx->inAudioStream->codec->bit_rate; 455 | ctx->configuration.audio_channels = ctx->inAudioStream->codec->channels; 456 | ctx->configuration.audio_frame_size = ctx->inAudioStream->codec->frame_size; 457 | ctx->configuration.audio_service_type = ctx->inAudioStream->codec->audio_service_type; 458 | ctx->configuration.audio_block_align = ctx->inAudioStream->codec->block_align; 459 | } 460 | 461 | printf("Video:\n"); 462 | printf("Stream avg numerator %d\n", ctx->configuration.avg_frame_rate_num); 463 | printf("Stream avg denominator %d\n", ctx->configuration.avg_frame_rate_den); 464 | printf("Average framerate: %f\n", ctx->configuration.avg_framerate); 465 | printf("Bitrate: %dk\n", ctx->configuration.video_bit_rate / 1000); 466 | printf("Duration: %ld\n", (long int) (ctx->inFormatCtx->duration / AV_TIME_BASE)); 467 | printf("Expected frames: %f\n", ctx->configuration.expected_total_frames); 468 | 469 | /* 470 | int64_t res = av_get_int(&ctx->inVideoStream->codec->priv_class, "muxrate", NULL); 471 | printf("muxrate set to %"PRId64"\n", res); 472 | */ 473 | 474 | if(ctx->audioStream != -1) { 475 | printf("Audio:\n"); 476 | printf("bit rate: %dk\n", ctx->configuration.audio_bit_rate / 1000); 477 | printf("Sample rate: %dk\n", ctx->configuration.audio_sample_rate / 1000); 478 | printf("Channels: %d\n", ctx->configuration.audio_channels); 479 | printf("Format: %s\n", av_get_sample_fmt_name(ctx->configuration.audio_sample_format)); 480 | } 481 | 482 | if(init_out(ctx, 0) < 0) 483 | return 0; 484 | 485 | ctx->outVideoStream->sample_aspect_ratio.num = ctx->configuration.sample_aspect_ratio_num; 486 | ctx->outVideoStream->sample_aspect_ratio.den = ctx->configuration.sample_aspect_ratio_den; 487 | 488 | printf("Opening output file: %s\n", argv[2]); 489 | 490 | if(ctx->outFormatCtx->oformat->flags & AVFMT_GLOBALHEADER) { 491 | ctx->outVideoCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER; 492 | ctx->outAudioCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER; 493 | } 494 | 495 | if (avio_open(&ctx->outFormatCtx->pb, argv[2], AVIO_FLAG_WRITE) < 0) { 496 | printf("Could not open '%s'\n", argv[2]); 497 | return -1; 498 | } 499 | 500 | /* Write the stream header, if any. */ 501 | if (avformat_write_header(ctx->outFormatCtx, NULL) < 0) { 502 | printf("Error writing header to output file\n"); 503 | return 1; 504 | } 505 | 506 | // Dump information about file 507 | av_dump_format(ctx->inFormatCtx, 0, argv[1], 0); 508 | av_dump_format(ctx->outFormatCtx, 0, argv[2], 1); 509 | 510 | ctx->start_time = ctx->inVideoStream->start_time; 511 | // ctx->configuration.expected_total_frames = ctx->configuration.avg_framerate * (((double)(pts[total_packets-1] - ctx->start_time + ctx->inVideoStream->start_time) / (double) (ctx->inVideoStream->start_time + ctx->inVideoStream->duration) * ctx->inFormatCtx->duration)/ AV_TIME_BASE); 512 | m_ptsOffset = av_rescale_q(ctx->start_time, ctx->inVideoStream->time_base, myAVTIMEBASEQ); 513 | printf("expected: %f duration: %" PRId64 " offset: %" PRId64 ", start %" PRId64 ", orig_start %" PRId64 "\n", ctx->configuration.expected_total_frames, ctx->inVideoStream->duration, m_ptsOffset, ctx->start_time, ctx->inVideoStream->start_time); 514 | 515 | pthread_create (&ctx->in_consumer, NULL, disk_writer, ctx); 516 | update_fps(ctx, 1); 517 | 518 | while(1) { 519 | if(abort_requested) 520 | break; 521 | 522 | av_init_packet(&ctx->inPacket); 523 | 524 | if(av_read_frame(ctx->inFormatCtx, &ctx->inPacket) < 0) { 525 | printf("\nend of input stream\n"); 526 | break; 527 | } 528 | 529 | if(ctx->inPacket.side_data_elems > 0) { 530 | printf("Sorry. Side data elements not supported in demuxed packets right now.\n"); 531 | exit(1); 532 | } 533 | 534 | // Is this a packet from the video stream? 535 | if(ctx->inPacket.stream_index==ctx->videoStream) { 536 | int speculative_frame_count = 1; 537 | queue_entry_t * e = malloc(ENTRYSIZE); 538 | Command * cmd = &e->cmd; 539 | assert(e); 540 | e->type = ctx->inPacket.stream_index; 541 | command__init(cmd); 542 | cmd->convert = &e->convert; 543 | convert__init(cmd->convert); 544 | cmd->convert->frame_number = ctx->configuration.frame_number; 545 | 546 | if(!ctx->ready_for_slaves) { 547 | if(!ctx->first_keyframe_reached && ctx->encoder_clean && ctx->drops_stopped) { 548 | if(ctx->inPacket.flags & AV_PKT_FLAG_KEY) { 549 | if(!ctx->remote) 550 | printf("\n"); 551 | printf("First clean keyframe reached\n"); 552 | ctx->first_keyframe_reached = 1; 553 | } 554 | } 555 | if(ctx->encoder_clean && ctx->drops_stopped && ctx->first_keyframe_reached) { 556 | if(!ctx->remote) 557 | printf("\n"); 558 | printf("Ready for slaves.\n"); 559 | ctx->ready_for_slaves = 1; 560 | } 561 | } 562 | 563 | while(ctx->remote && ctx->ready_for_slaves && ctx->num_slaves == 0 && !abort_requested) { 564 | printf("Waiting for slaves...\n"); 565 | sleep(1); 566 | } 567 | 568 | if(ctx->remote && ctx->ready_for_slaves) { 569 | if(ctx->inPacket.flags & AV_PKT_FLAG_KEY) 570 | icount++; 571 | 572 | if(ctx->curr_slave == NULL) { 573 | ctx->curr_slave = &ctx->slaves[0]; 574 | printf("\nSlave %d (%s) is ready for more work...\n", ctx->curr_slave->id, ctx->curr_slave->name); 575 | } else { 576 | if(icount == RANGESIZE && ctx->inPacket.flags & AV_PKT_FLAG_KEY) { 577 | int p; 578 | icount = 0; 579 | slave_t * not_busy = NULL, * curr; 580 | do { 581 | int print = ((ctx->in_fifo->size % 5) == 0); 582 | //my_select(ctx, &socks, 0); 583 | 584 | for(p = 0; p < ctx->num_slaves; p++) { 585 | curr = &ctx->slaves[p]; 586 | if(!curr->busy) { 587 | //if(!FD_ISSET(curr->fd, &socks)) { 588 | // printf("\nSlave %d (%s) is ready buffer is FULLLLLLLLLLL...\n", p, curr->ip); 589 | //} else { 590 | printf("\nSlave %d (%s) is ready for more work...\n", p, curr->name); 591 | not_busy = curr; 592 | //} 593 | } 594 | if(print) 595 | printf("Slave %d, (%s), queue %d, computed ranges %d, frames remaining this range: %d\n", 596 | curr->id, 597 | curr->name, 598 | curr->results->size, 599 | curr->ranges, 600 | curr->busy); 601 | } 602 | 603 | if(not_busy) { 604 | not_busy->ranges++; 605 | ctx->curr_slave = not_busy; 606 | ctx->curr_slave->ranges++; 607 | ctx->ranges++; 608 | break; 609 | } 610 | 611 | if(print) 612 | printf("(%d %%) (%d) All slaves busy, queue %d, fps: %f\n", 613 | (int) (((double) ctx->configuration.frame_number / (double) ctx->configuration.expected_total_frames) * 100), 614 | ctx->configuration.frame_number, 615 | ctx->in_fifo->size, 616 | ctx->fps); 617 | usleep(500000); 618 | } while(not_busy == NULL); 619 | } 620 | } 621 | } 622 | 623 | e->slave = ctx->curr_slave; 624 | e->m_pts = 0; 625 | e->current_frame_number = ctx->configuration.frame_number; 626 | 627 | if (ctx->inPacket.dts != AV_NOPTS_VALUE) { 628 | int64_t orig = ctx->inPacket.dts, rescaled; 629 | e->m_pts = av_rescale_q(ctx->inPacket.dts, ctx->inVideoStream->time_base, myAVTIMEBASEQ); 630 | e->m_pts -= m_ptsOffset; 631 | if(debug==2) 632 | printf("orig: %" PRId64 " rescaled %" PRId64 " with offset %" PRId64 "\n", 633 | orig, rescaled, e->m_pts); 634 | } 635 | 636 | e->inPts = (double)e->m_pts / AV_TIME_BASE; 637 | e->outFrames = e->inPts / av_q2d(ctx->outVideoCodecCtx->time_base); 638 | e->vdelta = e->outFrames - ctx->configuration.frame_number; 639 | 640 | if (e->vdelta < -1.1) { 641 | speculative_frame_count = 0; 642 | } else if (e->vdelta > 1.1) { 643 | speculative_frame_count = lrintf(e->vdelta); 644 | } 645 | 646 | cmd->convert->n_frame_count = speculative_frame_count; 647 | 648 | if(ctx->remote && ctx->ready_for_slaves) { 649 | int released_packet = 0; 650 | cmd->convert->packet = &e->packet; 651 | packet__init(cmd->convert->packet); 652 | packet_to_protobuf(cmd->convert->packet, &ctx->inPacket); 653 | e->save_packet = ctx->inPacket; 654 | 655 | if(icount == (RANGESIZE - 1)) { 656 | if(gop_length == 0) { 657 | if(debug==2) 658 | printf("\nStart Ending GOP @ %" PRId64 "\n", ctx->inPacket.pts); 659 | assert(ctx->inPacket.flags & AV_PKT_FLAG_KEY); 660 | } 661 | if(gop_length == MAX_EXPECTED_GOP_SIZE) { 662 | printf("\nHuge GOP, man, more than %d\n", MAX_EXPECTED_GOP_SIZE); 663 | exit(1); 664 | } 665 | gop_entries[gop_length++] = *e; 666 | released_packet = 1; 667 | } else if(icount == 0) { 668 | if(ctx->inPacket.flags & AV_PKT_FLAG_KEY) { 669 | if(gop_length > 0) { 670 | printf("\nRetransmit scene-change GOP @ %" PRId64 ", packets: %d, to slave: %d (%s)\n", 671 | gop_entries[0].cmd.convert->packet->pts, gop_length, e->slave->id, e->slave->name); 672 | 673 | for(y = 0; y < gop_length; y++) { 674 | queue_entry_t * ge = &gop_entries[y]; 675 | Command * gcmd = &ge->cmd; 676 | gcmd->code = TRANSCODE; 677 | gcmd->convert->do_not_reply = 1; 678 | got = cmdsend(e->slave->fd, e->slave->sbuf, gcmd); 679 | got = multiwrite(e->slave->fd, ge->save_packet.data, gcmd->convert->packet->size); 680 | if(got <= 0 || got != gcmd->convert->packet->size) { 681 | printf("gop wtf? %d / %d", got, gcmd->convert->packet->size); 682 | return -1; 683 | } 684 | 685 | av_free_packet(&ge->save_packet); 686 | } 687 | gop_length = 0; 688 | } 689 | } 690 | } 691 | 692 | cmd->code = TRANSCODE; 693 | got = cmdsend(e->slave->fd, e->slave->sbuf, cmd); 694 | got = multiwrite(e->slave->fd, ctx->inPacket.data, ctx->inPacket.size); 695 | if(got <= 0 || got != ctx->inPacket.size) { 696 | printf("regular wtf? %d / %d", got, ctx->inPacket.size); 697 | return -1; 698 | } 699 | 700 | if(released_packet == 0) 701 | av_free_packet(&ctx->inPacket); 702 | } else { 703 | if(debug==2) printf("local transcode %" PRId64 "\n", ctx->inPacket.pts); 704 | transcode(ctx, e, cmd->convert, &ctx->inPacket); 705 | update_fps(ctx, 0); 706 | store_transcode_result(&e->cmd, e); 707 | } 708 | 709 | 710 | if(ctx->remote && ctx->ready_for_slaves) { 711 | if(ctx->curr_slave) 712 | ctx->curr_slave->busy++; 713 | push(ctx->in_fifo, e); 714 | } else { 715 | if(debug==2) 716 | printf("skipping producer, outputting now.\n"); 717 | output_video(ctx, e, &e->cmd); 718 | /* 719 | * Don't farm packets until we've stopped dropping 720 | * them and the encoder is clean 721 | */ 722 | if(!ctx->drops_stopped && cmd->convert->n_frame_count == 0) { 723 | printf("drops finished\n"); 724 | ctx->drops_stopped = 1; 725 | } 726 | if(!ctx->encoder_clean && cmd->convert->extra_frame_count) { 727 | printf("encoder is clean\n"); 728 | ctx->encoder_clean = 1; 729 | ctx->configuration.frame_number += cmd->convert->extra_frame_count; 730 | } 731 | free(e); 732 | /* free local video transcode */ 733 | av_free_packet(&ctx->inPacket); 734 | } 735 | ctx->configuration.frame_number += speculative_frame_count; 736 | } else if(ctx->inPacket.stream_index == ctx->audioStream) { 737 | queue_entry_t * e = malloc(ENTRYSIZE); 738 | assert(e); 739 | e->save_packet = ctx->inPacket; 740 | e->type = ctx->inPacket.stream_index; 741 | push(ctx->in_fifo, e); 742 | } else { 743 | /* free unknown packet */ 744 | av_free_packet(&ctx->inPacket); 745 | } 746 | 747 | } 748 | printf("Stopping consumer.\n"); 749 | in_consumer_stop(ctx); 750 | 751 | if(ctx->remote) { 752 | int idx; 753 | Command cmd; 754 | Convert convert; 755 | slave_t * slave; 756 | 757 | command__init(&cmd); 758 | convert__init(&convert); 759 | cmd.convert = &convert; 760 | 761 | ctx->stop_listener = 1; 762 | shutdown(ctx->sockd, SHUT_RDWR); 763 | printf("Waiting for listener to close...\n"); 764 | pthread_join(ctx->listener, NULL); 765 | 766 | for(idx = 0; idx < ctx->num_slaves; idx++) { 767 | slave = &ctx->slaves[idx]; 768 | printf("Closing slave %d, ranges %d\n", slave->id, slave->ranges); 769 | cmd.code = TRANSCODE; 770 | cmd.convert->finished = 1; 771 | got = cmdsend(slave->fd, slave->sbuf, &cmd); 772 | close(slave->fd); 773 | } 774 | close(ctx->sockd); 775 | printf("Total ranges: %d\n", ctx->ranges); 776 | 777 | } 778 | 779 | if(gop_length > 0) { 780 | printf("Freeing last unused gop\n"); 781 | for(y = 0; y < gop_length; y++) 782 | av_free_packet(&gop_entries[y].save_packet); 783 | } 784 | 785 | printf("(100 %%) Finished: frames: %d\n", ctx->configuration.frame_number); 786 | 787 | 788 | av_write_trailer(ctx->outFormatCtx); 789 | avio_close(ctx->outFormatCtx->pb); 790 | 791 | /* Free the streams. */ 792 | for (x = 0; x < ctx->outFormatCtx->nb_streams; x++) { 793 | av_freep(&ctx->outFormatCtx->streams[x]->codec); 794 | av_freep(&ctx->outFormatCtx->streams[x]); 795 | } 796 | 797 | avformat_close_input(&ctx->inFormatCtx); 798 | destroy_ctx(ctx); 799 | return 0; 800 | } 801 | -------------------------------------------------------------------------------- /missing: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Common stub for a few missing GNU programs while installing. 3 | 4 | scriptversion=2012-01-06.13; # UTC 5 | 6 | # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 7 | # 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. 8 | # Originally by Fran,cois Pinard , 1996. 9 | 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 2, or (at your option) 13 | # any later version. 14 | 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | 23 | # As a special exception to the GNU General Public License, if you 24 | # distribute this file as part of a program that contains a 25 | # configuration script generated by Autoconf, you may include it under 26 | # the same distribution terms that you use for the rest of that program. 27 | 28 | if test $# -eq 0; then 29 | echo 1>&2 "Try \`$0 --help' for more information" 30 | exit 1 31 | fi 32 | 33 | run=: 34 | sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' 35 | sed_minuso='s/.* -o \([^ ]*\).*/\1/p' 36 | 37 | # In the cases where this matters, `missing' is being run in the 38 | # srcdir already. 39 | if test -f configure.ac; then 40 | configure_ac=configure.ac 41 | else 42 | configure_ac=configure.in 43 | fi 44 | 45 | msg="missing on your system" 46 | 47 | case $1 in 48 | --run) 49 | # Try to run requested program, and just exit if it succeeds. 50 | run= 51 | shift 52 | "$@" && exit 0 53 | # Exit code 63 means version mismatch. This often happens 54 | # when the user try to use an ancient version of a tool on 55 | # a file that requires a minimum version. In this case we 56 | # we should proceed has if the program had been absent, or 57 | # if --run hadn't been passed. 58 | if test $? = 63; then 59 | run=: 60 | msg="probably too old" 61 | fi 62 | ;; 63 | 64 | -h|--h|--he|--hel|--help) 65 | echo "\ 66 | $0 [OPTION]... PROGRAM [ARGUMENT]... 67 | 68 | Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an 69 | error status if there is no known handling for PROGRAM. 70 | 71 | Options: 72 | -h, --help display this help and exit 73 | -v, --version output version information and exit 74 | --run try to run the given command, and emulate it if it fails 75 | 76 | Supported PROGRAM values: 77 | aclocal touch file \`aclocal.m4' 78 | autoconf touch file \`configure' 79 | autoheader touch file \`config.h.in' 80 | autom4te touch the output file, or create a stub one 81 | automake touch all \`Makefile.in' files 82 | bison create \`y.tab.[ch]', if possible, from existing .[ch] 83 | flex create \`lex.yy.c', if possible, from existing .c 84 | help2man touch the output file 85 | lex create \`lex.yy.c', if possible, from existing .c 86 | makeinfo touch the output file 87 | yacc create \`y.tab.[ch]', if possible, from existing .[ch] 88 | 89 | Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and 90 | \`g' are ignored when checking the name. 91 | 92 | Send bug reports to ." 93 | exit $? 94 | ;; 95 | 96 | -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 97 | echo "missing $scriptversion (GNU Automake)" 98 | exit $? 99 | ;; 100 | 101 | -*) 102 | echo 1>&2 "$0: Unknown \`$1' option" 103 | echo 1>&2 "Try \`$0 --help' for more information" 104 | exit 1 105 | ;; 106 | 107 | esac 108 | 109 | # normalize program name to check for. 110 | program=`echo "$1" | sed ' 111 | s/^gnu-//; t 112 | s/^gnu//; t 113 | s/^g//; t'` 114 | 115 | # Now exit if we have it, but it failed. Also exit now if we 116 | # don't have it and --version was passed (most likely to detect 117 | # the program). This is about non-GNU programs, so use $1 not 118 | # $program. 119 | case $1 in 120 | lex*|yacc*) 121 | # Not GNU programs, they don't have --version. 122 | ;; 123 | 124 | *) 125 | if test -z "$run" && ($1 --version) > /dev/null 2>&1; then 126 | # We have it, but it failed. 127 | exit 1 128 | elif test "x$2" = "x--version" || test "x$2" = "x--help"; then 129 | # Could not run --version or --help. This is probably someone 130 | # running `$TOOL --version' or `$TOOL --help' to check whether 131 | # $TOOL exists and not knowing $TOOL uses missing. 132 | exit 1 133 | fi 134 | ;; 135 | esac 136 | 137 | # If it does not exist, or fails to run (possibly an outdated version), 138 | # try to emulate it. 139 | case $program in 140 | aclocal*) 141 | echo 1>&2 "\ 142 | WARNING: \`$1' is $msg. You should only need it if 143 | you modified \`acinclude.m4' or \`${configure_ac}'. You might want 144 | to install the \`Automake' and \`Perl' packages. Grab them from 145 | any GNU archive site." 146 | touch aclocal.m4 147 | ;; 148 | 149 | autoconf*) 150 | echo 1>&2 "\ 151 | WARNING: \`$1' is $msg. You should only need it if 152 | you modified \`${configure_ac}'. You might want to install the 153 | \`Autoconf' and \`GNU m4' packages. Grab them from any GNU 154 | archive site." 155 | touch configure 156 | ;; 157 | 158 | autoheader*) 159 | echo 1>&2 "\ 160 | WARNING: \`$1' is $msg. You should only need it if 161 | you modified \`acconfig.h' or \`${configure_ac}'. You might want 162 | to install the \`Autoconf' and \`GNU m4' packages. Grab them 163 | from any GNU archive site." 164 | files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` 165 | test -z "$files" && files="config.h" 166 | touch_files= 167 | for f in $files; do 168 | case $f in 169 | *:*) touch_files="$touch_files "`echo "$f" | 170 | sed -e 's/^[^:]*://' -e 's/:.*//'`;; 171 | *) touch_files="$touch_files $f.in";; 172 | esac 173 | done 174 | touch $touch_files 175 | ;; 176 | 177 | automake*) 178 | echo 1>&2 "\ 179 | WARNING: \`$1' is $msg. You should only need it if 180 | you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. 181 | You might want to install the \`Automake' and \`Perl' packages. 182 | Grab them from any GNU archive site." 183 | find . -type f -name Makefile.am -print | 184 | sed 's/\.am$/.in/' | 185 | while read f; do touch "$f"; done 186 | ;; 187 | 188 | autom4te*) 189 | echo 1>&2 "\ 190 | WARNING: \`$1' is needed, but is $msg. 191 | You might have modified some files without having the 192 | proper tools for further handling them. 193 | You can get \`$1' as part of \`Autoconf' from any GNU 194 | archive site." 195 | 196 | file=`echo "$*" | sed -n "$sed_output"` 197 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 198 | if test -f "$file"; then 199 | touch $file 200 | else 201 | test -z "$file" || exec >$file 202 | echo "#! /bin/sh" 203 | echo "# Created by GNU Automake missing as a replacement of" 204 | echo "# $ $@" 205 | echo "exit 0" 206 | chmod +x $file 207 | exit 1 208 | fi 209 | ;; 210 | 211 | bison*|yacc*) 212 | echo 1>&2 "\ 213 | WARNING: \`$1' $msg. You should only need it if 214 | you modified a \`.y' file. You may need the \`Bison' package 215 | in order for those modifications to take effect. You can get 216 | \`Bison' from any GNU archive site." 217 | rm -f y.tab.c y.tab.h 218 | if test $# -ne 1; then 219 | eval LASTARG=\${$#} 220 | case $LASTARG in 221 | *.y) 222 | SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` 223 | if test -f "$SRCFILE"; then 224 | cp "$SRCFILE" y.tab.c 225 | fi 226 | SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` 227 | if test -f "$SRCFILE"; then 228 | cp "$SRCFILE" y.tab.h 229 | fi 230 | ;; 231 | esac 232 | fi 233 | if test ! -f y.tab.h; then 234 | echo >y.tab.h 235 | fi 236 | if test ! -f y.tab.c; then 237 | echo 'main() { return 0; }' >y.tab.c 238 | fi 239 | ;; 240 | 241 | lex*|flex*) 242 | echo 1>&2 "\ 243 | WARNING: \`$1' is $msg. You should only need it if 244 | you modified a \`.l' file. You may need the \`Flex' package 245 | in order for those modifications to take effect. You can get 246 | \`Flex' from any GNU archive site." 247 | rm -f lex.yy.c 248 | if test $# -ne 1; then 249 | eval LASTARG=\${$#} 250 | case $LASTARG in 251 | *.l) 252 | SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` 253 | if test -f "$SRCFILE"; then 254 | cp "$SRCFILE" lex.yy.c 255 | fi 256 | ;; 257 | esac 258 | fi 259 | if test ! -f lex.yy.c; then 260 | echo 'main() { return 0; }' >lex.yy.c 261 | fi 262 | ;; 263 | 264 | help2man*) 265 | echo 1>&2 "\ 266 | WARNING: \`$1' is $msg. You should only need it if 267 | you modified a dependency of a manual page. You may need the 268 | \`Help2man' package in order for those modifications to take 269 | effect. You can get \`Help2man' from any GNU archive site." 270 | 271 | file=`echo "$*" | sed -n "$sed_output"` 272 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 273 | if test -f "$file"; then 274 | touch $file 275 | else 276 | test -z "$file" || exec >$file 277 | echo ".ab help2man is required to generate this page" 278 | exit $? 279 | fi 280 | ;; 281 | 282 | makeinfo*) 283 | echo 1>&2 "\ 284 | WARNING: \`$1' is $msg. You should only need it if 285 | you modified a \`.texi' or \`.texinfo' file, or any other file 286 | indirectly affecting the aspect of the manual. The spurious 287 | call might also be the consequence of using a buggy \`make' (AIX, 288 | DU, IRIX). You might want to install the \`Texinfo' package or 289 | the \`GNU make' package. Grab either from any GNU archive site." 290 | # The file to touch is that specified with -o ... 291 | file=`echo "$*" | sed -n "$sed_output"` 292 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 293 | if test -z "$file"; then 294 | # ... or it is the one specified with @setfilename ... 295 | infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` 296 | file=`sed -n ' 297 | /^@setfilename/{ 298 | s/.* \([^ ]*\) *$/\1/ 299 | p 300 | q 301 | }' $infile` 302 | # ... or it is derived from the source name (dir/f.texi becomes f.info) 303 | test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info 304 | fi 305 | # If the file does not exist, the user really needs makeinfo; 306 | # let's fail without touching anything. 307 | test -f $file || exit 1 308 | touch $file 309 | ;; 310 | 311 | *) 312 | echo 1>&2 "\ 313 | WARNING: \`$1' is needed, and is $msg. 314 | You might have modified some files without having the 315 | proper tools for further handling them. Check the \`README' file, 316 | it often tells you about the needed prerequisites for installing 317 | this package. You may also peek at any GNU archive site, in case 318 | some other package would contain this missing \`$1' program." 319 | exit 1 320 | ;; 321 | esac 322 | 323 | exit 0 324 | 325 | # Local variables: 326 | # eval: (add-hook 'write-file-hooks 'time-stamp) 327 | # time-stamp-start: "scriptversion=" 328 | # time-stamp-format: "%:y-%02m-%02d.%02H" 329 | # time-stamp-time-zone: "UTC" 330 | # time-stamp-end: "; # UTC" 331 | # End: 332 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | # Just a helper script for running stuff 4 | 5 | #file="../orig.mpg" 6 | #file="../st.m2ts" 7 | #file="/storage/recordings_readable/bytitle/Star Trek- First Contact/20121004-2100-2330- Untitled.mpg" 8 | file="/storage/recordings_readable/bytitle/Star Trek II- The Wrath of Khan/20121203-2230-0100- Untitled.mpg" 9 | #file="/storage/recordings_readable/bytitle/Star Trek III- The Search for Spock/20121004-1100-1330- Untitled.mpg" 10 | #file="sample.mpg" 11 | #file="sample2.mpg" 12 | #file="sample3.mpg" 13 | #file="../sample.m2ts" 14 | 15 | #dir=$(echo "$file" | grep -oE ".*\/") 16 | dir=/home/mrhines/mythtv_to_dvd/ 17 | sudo chmod 777 "$dir" 18 | 19 | #video="${dir}output.m2ts" 20 | video="${dir}output.mkv" 21 | 22 | echo "input: $file" 23 | echo "output: $video" 24 | 25 | if [ x"$1" != xslave ] ; then 26 | rm -f "$video" 27 | fi 28 | 29 | # Rebuild in case of any changes 30 | make 31 | 32 | 33 | if [ $? -eq 0 ] ; then 34 | if [ x"$1" == xslave ] ; then 35 | rm -f luvi_slave_$(hostname).log 36 | #gdb ~/mythtv_to_dvd/luvi/luvi_slave -ex "run $2 1264" 37 | nice -n 19 ~/mythtv_to_dvd/luvi/luvi_slave $2 1264 38 | else 39 | rm -f luvi_master.log 40 | #gdb ~/mythtv_to_dvd/luvi/luvi_master -ex "run \"${file}\" \"$video\" 1264 1" 41 | #nice -n 19 ~/mythtv_to_dvd/luvi/luvi_master "${file}" "$video" 1264 0 42 | nice -n 19 ~/mythtv_to_dvd/luvi/luvi_master "${file}" "$video" 1264 1 43 | fi 44 | fi 45 | -------------------------------------------------------------------------------- /slave.c: -------------------------------------------------------------------------------- 1 | #include "luvi.h" 2 | 3 | static void * video_transcoder(void * opaque) 4 | { 5 | Context * ctx = opaque; 6 | queue_entry_t * e; 7 | 8 | while(1) { 9 | if(!(e = pop(ctx->in_fifo, &ctx->stop_in_consumer))) 10 | break; 11 | 12 | // transcoding parameters for this frame 13 | protobuf_to_packet(&e->save_packet, e->recv->convert->packet); 14 | 15 | // go! 16 | e->got_packet = transcode(ctx, e, e->recv->convert, &e->save_packet); 17 | update_fps(ctx, 0); 18 | 19 | /* 20 | * Free the original data. Resulting coded frame is 21 | * stored in e->outBuffers 22 | */ 23 | av_free_packet(&e->save_packet); 24 | 25 | push(ctx->out_fifo, e); 26 | } 27 | } 28 | 29 | static void * network_writer(void * opaque) 30 | { 31 | Context * ctx = opaque; 32 | queue_entry_t * e; 33 | Command send; 34 | Convert convert; 35 | uint8_t buf[MAX_MSG_SIZE]; 36 | int x, 37 | ret; 38 | 39 | 40 | while(1) { 41 | if(!(e = pop(ctx->out_fifo, &ctx->stop_out_consumer))) 42 | break; 43 | 44 | /* 45 | * Packet data has been previous allocated. 46 | * Prepare response area. 47 | */ 48 | command__init(&send); 49 | send.convert = &convert; 50 | convert__init(&convert); 51 | 52 | // prepare response to master 53 | send.convert->buffers = e->recv->convert->buffers; 54 | send.convert->extra_frame_count = e->recv->convert->extra_frame_count; 55 | send.convert->frame_number = e->recv->convert->frame_number; 56 | send.convert->n_frame_count = e->recv->convert->n_frame_count; 57 | 58 | store_transcode_result(&send, e); 59 | 60 | // if transcoding produced a frame, send the corresponding buffers 61 | if(e->recv->convert->do_not_reply == 0) { 62 | // Tell master what this is 63 | send.code = TRANSCODE_RESULT; 64 | cmdsend(e->fd, buf, &send); 65 | 66 | if(e->got_packet) { 67 | /* Send raw data */ 68 | for(x = 0; x < send.convert->buffers; x++) { 69 | ret = multiwrite(e->fd, e->outBuffers[x], e->buffer_lengths[x]); 70 | if(ret <= 0) { 71 | perror("write"); 72 | printf("Failed to send output packet payloads.\n"); 73 | exit(1); 74 | } 75 | } 76 | } 77 | } 78 | 79 | for(x = 0; x < send.convert->buffers; x++) 80 | av_free(e->outBuffers[x]); 81 | 82 | command__free_unpacked(e->recv, NULL); 83 | free(e); 84 | } 85 | } 86 | 87 | int main(int argc, char * argv[]) { 88 | Command * cmd, 89 | send; 90 | struct addrinfo * raddr; 91 | struct sockaddr_in saddr; 92 | int rport, 93 | fd, 94 | ret, 95 | rcvbuff = NETWORK_BUFFER, 96 | sendbuff = NETWORK_BUFFER, 97 | res; 98 | char rip[20]; 99 | pthread_t pro; 100 | uint8_t buf[MAX_MSG_SIZE]; 101 | Context * ctx; 102 | 103 | ctx = malloc(sizeof(Context)); 104 | 105 | if(init_ctx(ctx, QUEUESIZE) < 0) 106 | return -1; 107 | 108 | if(argc < 3) { 109 | printf("Usage: \n"); 110 | exit(1); 111 | } 112 | 113 | raddr = gethost(argv[1]); 114 | strcpy(rip, inet_ntoa(((struct sockaddr_in *) raddr->ai_addr)->sin_addr)); 115 | printf("%s mapped to %s\n", argv[1], rip); 116 | 117 | rport = atoi(argv[2]); 118 | 119 | if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 120 | perror(""); 121 | exit(1); 122 | } 123 | 124 | bzero(&saddr, sizeof(saddr)); 125 | saddr.sin_family = AF_INET; 126 | saddr.sin_addr.s_addr = inet_addr(rip); 127 | saddr.sin_port = htons(rport); /* daytime server */ 128 | 129 | if(connect(fd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in)) < 0) { 130 | perror("connect"); 131 | exit(1); 132 | } 133 | 134 | res = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuff, sizeof(rcvbuff)); 135 | 136 | if(res < 0) { 137 | perror("setsockopt: receive buffer:"); 138 | printf("Failed to increase new slave's receive buffer\n"); 139 | exit(1); 140 | } 141 | 142 | res = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)); 143 | 144 | if(res < 0) { 145 | perror("setsockopt: send buffer:"); 146 | printf("Failed to increase new slave's send buffer\n"); 147 | exit(1); 148 | } 149 | 150 | printf("== connected %d with buffer %d %d\n", fd, sendbuff, rcvbuff); 151 | 152 | // Announce ourselves to the master and ask for work to do 153 | command__init(&send); 154 | send.code = INIT; 155 | send.name = ctx->hostname; 156 | ret = cmdsend(fd, buf, &send); 157 | ret = cmdrecv(fd, buf, &cmd, CODEC); 158 | memcpy(&ctx->configuration, cmd->configuration, sizeof(Config)); 159 | command__free_unpacked(cmd, NULL); 160 | 161 | if(init_in(ctx, 1) < 0) 162 | return -1; 163 | 164 | if(init_out(ctx, 1) < 0) 165 | return -1; 166 | 167 | pthread_create (&ctx->in_consumer, NULL, video_transcoder, ctx); 168 | pthread_create (&ctx->out_consumer, NULL, network_writer, ctx); 169 | 170 | update_fps(ctx, 1); 171 | 172 | // Run until there is no more work to do 173 | while(1) { 174 | queue_entry_t * e = malloc(ENTRYSIZE); 175 | int x, size; 176 | void * destruct, * data; 177 | 178 | /* 179 | * Receive parameters to transcode one frame. 180 | * An entire GOP will follow. 181 | */ 182 | cmdrecv(fd, buf, &e->recv, TRANSCODE); 183 | 184 | if(e->recv->convert->finished) { 185 | printf("\nEncoding complete.\n"); 186 | break; 187 | } 188 | 189 | /* 190 | * Pull in the raw packet data corresponding to this frame 191 | * for transcoding. 192 | */ 193 | size = e->recv->convert->packet->size; 194 | 195 | // Allocate space to receive the data 196 | av_new_packet(&e->save_packet, size); 197 | e->fd = fd; 198 | multirecv(fd, e->save_packet.data, size); 199 | 200 | // Send to FIFO for transcoding 201 | push(ctx->in_fifo, e); 202 | } 203 | 204 | // Wait for remaining transcodes to complete 205 | in_consumer_stop(ctx); 206 | out_consumer_stop(ctx); 207 | printf("Finished!\n"); 208 | close(fd); 209 | destroy_ctx(ctx); 210 | freeaddrinfo(raddr); 211 | } 212 | --------------------------------------------------------------------------------