1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/gst-gmyth/AUTHORS Tue May 01 16:04:02 2007 +0100
1.3 @@ -0,0 +1,4 @@
1.4 +Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
1.5 +Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
1.6 +Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
1.7 +Rosfran Lins Borges <rosfran.borges@indt.org.br>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/gst-gmyth/COPYING Tue May 01 16:04:02 2007 +0100
2.3 @@ -0,0 +1,504 @@
2.4 + GNU LESSER GENERAL PUBLIC LICENSE
2.5 + Version 2.1, February 1999
2.6 +
2.7 + Copyright (C) 1991, 1999 Free Software Foundation, Inc.
2.8 + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2.9 + Everyone is permitted to copy and distribute verbatim copies
2.10 + of this license document, but changing it is not allowed.
2.11 +
2.12 +[This is the first released version of the Lesser GPL. It also counts
2.13 + as the successor of the GNU Library Public License, version 2, hence
2.14 + the version number 2.1.]
2.15 +
2.16 + Preamble
2.17 +
2.18 + The licenses for most software are designed to take away your
2.19 +freedom to share and change it. By contrast, the GNU General Public
2.20 +Licenses are intended to guarantee your freedom to share and change
2.21 +free software--to make sure the software is free for all its users.
2.22 +
2.23 + This license, the Lesser General Public License, applies to some
2.24 +specially designated software packages--typically libraries--of the
2.25 +Free Software Foundation and other authors who decide to use it. You
2.26 +can use it too, but we suggest you first think carefully about whether
2.27 +this license or the ordinary General Public License is the better
2.28 +strategy to use in any particular case, based on the explanations below.
2.29 +
2.30 + When we speak of free software, we are referring to freedom of use,
2.31 +not price. Our General Public Licenses are designed to make sure that
2.32 +you have the freedom to distribute copies of free software (and charge
2.33 +for this service if you wish); that you receive source code or can get
2.34 +it if you want it; that you can change the software and use pieces of
2.35 +it in new free programs; and that you are informed that you can do
2.36 +these things.
2.37 +
2.38 + To protect your rights, we need to make restrictions that forbid
2.39 +distributors to deny you these rights or to ask you to surrender these
2.40 +rights. These restrictions translate to certain responsibilities for
2.41 +you if you distribute copies of the library or if you modify it.
2.42 +
2.43 + For example, if you distribute copies of the library, whether gratis
2.44 +or for a fee, you must give the recipients all the rights that we gave
2.45 +you. You must make sure that they, too, receive or can get the source
2.46 +code. If you link other code with the library, you must provide
2.47 +complete object files to the recipients, so that they can relink them
2.48 +with the library after making changes to the library and recompiling
2.49 +it. And you must show them these terms so they know their rights.
2.50 +
2.51 + We protect your rights with a two-step method: (1) we copyright the
2.52 +library, and (2) we offer you this license, which gives you legal
2.53 +permission to copy, distribute and/or modify the library.
2.54 +
2.55 + To protect each distributor, we want to make it very clear that
2.56 +there is no warranty for the free library. Also, if the library is
2.57 +modified by someone else and passed on, the recipients should know
2.58 +that what they have is not the original version, so that the original
2.59 +author's reputation will not be affected by problems that might be
2.60 +introduced by others.
2.61 +
2.62 + Finally, software patents pose a constant threat to the existence of
2.63 +any free program. We wish to make sure that a company cannot
2.64 +effectively restrict the users of a free program by obtaining a
2.65 +restrictive license from a patent holder. Therefore, we insist that
2.66 +any patent license obtained for a version of the library must be
2.67 +consistent with the full freedom of use specified in this license.
2.68 +
2.69 + Most GNU software, including some libraries, is covered by the
2.70 +ordinary GNU General Public License. This license, the GNU Lesser
2.71 +General Public License, applies to certain designated libraries, and
2.72 +is quite different from the ordinary General Public License. We use
2.73 +this license for certain libraries in order to permit linking those
2.74 +libraries into non-free programs.
2.75 +
2.76 + When a program is linked with a library, whether statically or using
2.77 +a shared library, the combination of the two is legally speaking a
2.78 +combined work, a derivative of the original library. The ordinary
2.79 +General Public License therefore permits such linking only if the
2.80 +entire combination fits its criteria of freedom. The Lesser General
2.81 +Public License permits more lax criteria for linking other code with
2.82 +the library.
2.83 +
2.84 + We call this license the "Lesser" General Public License because it
2.85 +does Less to protect the user's freedom than the ordinary General
2.86 +Public License. It also provides other free software developers Less
2.87 +of an advantage over competing non-free programs. These disadvantages
2.88 +are the reason we use the ordinary General Public License for many
2.89 +libraries. However, the Lesser license provides advantages in certain
2.90 +special circumstances.
2.91 +
2.92 + For example, on rare occasions, there may be a special need to
2.93 +encourage the widest possible use of a certain library, so that it becomes
2.94 +a de-facto standard. To achieve this, non-free programs must be
2.95 +allowed to use the library. A more frequent case is that a free
2.96 +library does the same job as widely used non-free libraries. In this
2.97 +case, there is little to gain by limiting the free library to free
2.98 +software only, so we use the Lesser General Public License.
2.99 +
2.100 + In other cases, permission to use a particular library in non-free
2.101 +programs enables a greater number of people to use a large body of
2.102 +free software. For example, permission to use the GNU C Library in
2.103 +non-free programs enables many more people to use the whole GNU
2.104 +operating system, as well as its variant, the GNU/Linux operating
2.105 +system.
2.106 +
2.107 + Although the Lesser General Public License is Less protective of the
2.108 +users' freedom, it does ensure that the user of a program that is
2.109 +linked with the Library has the freedom and the wherewithal to run
2.110 +that program using a modified version of the Library.
2.111 +
2.112 + The precise terms and conditions for copying, distribution and
2.113 +modification follow. Pay close attention to the difference between a
2.114 +"work based on the library" and a "work that uses the library". The
2.115 +former contains code derived from the library, whereas the latter must
2.116 +be combined with the library in order to run.
2.117 +
2.118 + GNU LESSER GENERAL PUBLIC LICENSE
2.119 + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
2.120 +
2.121 + 0. This License Agreement applies to any software library or other
2.122 +program which contains a notice placed by the copyright holder or
2.123 +other authorized party saying it may be distributed under the terms of
2.124 +this Lesser General Public License (also called "this License").
2.125 +Each licensee is addressed as "you".
2.126 +
2.127 + A "library" means a collection of software functions and/or data
2.128 +prepared so as to be conveniently linked with application programs
2.129 +(which use some of those functions and data) to form executables.
2.130 +
2.131 + The "Library", below, refers to any such software library or work
2.132 +which has been distributed under these terms. A "work based on the
2.133 +Library" means either the Library or any derivative work under
2.134 +copyright law: that is to say, a work containing the Library or a
2.135 +portion of it, either verbatim or with modifications and/or translated
2.136 +straightforwardly into another language. (Hereinafter, translation is
2.137 +included without limitation in the term "modification".)
2.138 +
2.139 + "Source code" for a work means the preferred form of the work for
2.140 +making modifications to it. For a library, complete source code means
2.141 +all the source code for all modules it contains, plus any associated
2.142 +interface definition files, plus the scripts used to control compilation
2.143 +and installation of the library.
2.144 +
2.145 + Activities other than copying, distribution and modification are not
2.146 +covered by this License; they are outside its scope. The act of
2.147 +running a program using the Library is not restricted, and output from
2.148 +such a program is covered only if its contents constitute a work based
2.149 +on the Library (independent of the use of the Library in a tool for
2.150 +writing it). Whether that is true depends on what the Library does
2.151 +and what the program that uses the Library does.
2.152 +
2.153 + 1. You may copy and distribute verbatim copies of the Library's
2.154 +complete source code as you receive it, in any medium, provided that
2.155 +you conspicuously and appropriately publish on each copy an
2.156 +appropriate copyright notice and disclaimer of warranty; keep intact
2.157 +all the notices that refer to this License and to the absence of any
2.158 +warranty; and distribute a copy of this License along with the
2.159 +Library.
2.160 +
2.161 + You may charge a fee for the physical act of transferring a copy,
2.162 +and you may at your option offer warranty protection in exchange for a
2.163 +fee.
2.164 +
2.165 + 2. You may modify your copy or copies of the Library or any portion
2.166 +of it, thus forming a work based on the Library, and copy and
2.167 +distribute such modifications or work under the terms of Section 1
2.168 +above, provided that you also meet all of these conditions:
2.169 +
2.170 + a) The modified work must itself be a software library.
2.171 +
2.172 + b) You must cause the files modified to carry prominent notices
2.173 + stating that you changed the files and the date of any change.
2.174 +
2.175 + c) You must cause the whole of the work to be licensed at no
2.176 + charge to all third parties under the terms of this License.
2.177 +
2.178 + d) If a facility in the modified Library refers to a function or a
2.179 + table of data to be supplied by an application program that uses
2.180 + the facility, other than as an argument passed when the facility
2.181 + is invoked, then you must make a good faith effort to ensure that,
2.182 + in the event an application does not supply such function or
2.183 + table, the facility still operates, and performs whatever part of
2.184 + its purpose remains meaningful.
2.185 +
2.186 + (For example, a function in a library to compute square roots has
2.187 + a purpose that is entirely well-defined independent of the
2.188 + application. Therefore, Subsection 2d requires that any
2.189 + application-supplied function or table used by this function must
2.190 + be optional: if the application does not supply it, the square
2.191 + root function must still compute square roots.)
2.192 +
2.193 +These requirements apply to the modified work as a whole. If
2.194 +identifiable sections of that work are not derived from the Library,
2.195 +and can be reasonably considered independent and separate works in
2.196 +themselves, then this License, and its terms, do not apply to those
2.197 +sections when you distribute them as separate works. But when you
2.198 +distribute the same sections as part of a whole which is a work based
2.199 +on the Library, the distribution of the whole must be on the terms of
2.200 +this License, whose permissions for other licensees extend to the
2.201 +entire whole, and thus to each and every part regardless of who wrote
2.202 +it.
2.203 +
2.204 +Thus, it is not the intent of this section to claim rights or contest
2.205 +your rights to work written entirely by you; rather, the intent is to
2.206 +exercise the right to control the distribution of derivative or
2.207 +collective works based on the Library.
2.208 +
2.209 +In addition, mere aggregation of another work not based on the Library
2.210 +with the Library (or with a work based on the Library) on a volume of
2.211 +a storage or distribution medium does not bring the other work under
2.212 +the scope of this License.
2.213 +
2.214 + 3. You may opt to apply the terms of the ordinary GNU General Public
2.215 +License instead of this License to a given copy of the Library. To do
2.216 +this, you must alter all the notices that refer to this License, so
2.217 +that they refer to the ordinary GNU General Public License, version 2,
2.218 +instead of to this License. (If a newer version than version 2 of the
2.219 +ordinary GNU General Public License has appeared, then you can specify
2.220 +that version instead if you wish.) Do not make any other change in
2.221 +these notices.
2.222 +
2.223 + Once this change is made in a given copy, it is irreversible for
2.224 +that copy, so the ordinary GNU General Public License applies to all
2.225 +subsequent copies and derivative works made from that copy.
2.226 +
2.227 + This option is useful when you wish to copy part of the code of
2.228 +the Library into a program that is not a library.
2.229 +
2.230 + 4. You may copy and distribute the Library (or a portion or
2.231 +derivative of it, under Section 2) in object code or executable form
2.232 +under the terms of Sections 1 and 2 above provided that you accompany
2.233 +it with the complete corresponding machine-readable source code, which
2.234 +must be distributed under the terms of Sections 1 and 2 above on a
2.235 +medium customarily used for software interchange.
2.236 +
2.237 + If distribution of object code is made by offering access to copy
2.238 +from a designated place, then offering equivalent access to copy the
2.239 +source code from the same place satisfies the requirement to
2.240 +distribute the source code, even though third parties are not
2.241 +compelled to copy the source along with the object code.
2.242 +
2.243 + 5. A program that contains no derivative of any portion of the
2.244 +Library, but is designed to work with the Library by being compiled or
2.245 +linked with it, is called a "work that uses the Library". Such a
2.246 +work, in isolation, is not a derivative work of the Library, and
2.247 +therefore falls outside the scope of this License.
2.248 +
2.249 + However, linking a "work that uses the Library" with the Library
2.250 +creates an executable that is a derivative of the Library (because it
2.251 +contains portions of the Library), rather than a "work that uses the
2.252 +library". The executable is therefore covered by this License.
2.253 +Section 6 states terms for distribution of such executables.
2.254 +
2.255 + When a "work that uses the Library" uses material from a header file
2.256 +that is part of the Library, the object code for the work may be a
2.257 +derivative work of the Library even though the source code is not.
2.258 +Whether this is true is especially significant if the work can be
2.259 +linked without the Library, or if the work is itself a library. The
2.260 +threshold for this to be true is not precisely defined by law.
2.261 +
2.262 + If such an object file uses only numerical parameters, data
2.263 +structure layouts and accessors, and small macros and small inline
2.264 +functions (ten lines or less in length), then the use of the object
2.265 +file is unrestricted, regardless of whether it is legally a derivative
2.266 +work. (Executables containing this object code plus portions of the
2.267 +Library will still fall under Section 6.)
2.268 +
2.269 + Otherwise, if the work is a derivative of the Library, you may
2.270 +distribute the object code for the work under the terms of Section 6.
2.271 +Any executables containing that work also fall under Section 6,
2.272 +whether or not they are linked directly with the Library itself.
2.273 +
2.274 + 6. As an exception to the Sections above, you may also combine or
2.275 +link a "work that uses the Library" with the Library to produce a
2.276 +work containing portions of the Library, and distribute that work
2.277 +under terms of your choice, provided that the terms permit
2.278 +modification of the work for the customer's own use and reverse
2.279 +engineering for debugging such modifications.
2.280 +
2.281 + You must give prominent notice with each copy of the work that the
2.282 +Library is used in it and that the Library and its use are covered by
2.283 +this License. You must supply a copy of this License. If the work
2.284 +during execution displays copyright notices, you must include the
2.285 +copyright notice for the Library among them, as well as a reference
2.286 +directing the user to the copy of this License. Also, you must do one
2.287 +of these things:
2.288 +
2.289 + a) Accompany the work with the complete corresponding
2.290 + machine-readable source code for the Library including whatever
2.291 + changes were used in the work (which must be distributed under
2.292 + Sections 1 and 2 above); and, if the work is an executable linked
2.293 + with the Library, with the complete machine-readable "work that
2.294 + uses the Library", as object code and/or source code, so that the
2.295 + user can modify the Library and then relink to produce a modified
2.296 + executable containing the modified Library. (It is understood
2.297 + that the user who changes the contents of definitions files in the
2.298 + Library will not necessarily be able to recompile the application
2.299 + to use the modified definitions.)
2.300 +
2.301 + b) Use a suitable shared library mechanism for linking with the
2.302 + Library. A suitable mechanism is one that (1) uses at run time a
2.303 + copy of the library already present on the user's computer system,
2.304 + rather than copying library functions into the executable, and (2)
2.305 + will operate properly with a modified version of the library, if
2.306 + the user installs one, as long as the modified version is
2.307 + interface-compatible with the version that the work was made with.
2.308 +
2.309 + c) Accompany the work with a written offer, valid for at
2.310 + least three years, to give the same user the materials
2.311 + specified in Subsection 6a, above, for a charge no more
2.312 + than the cost of performing this distribution.
2.313 +
2.314 + d) If distribution of the work is made by offering access to copy
2.315 + from a designated place, offer equivalent access to copy the above
2.316 + specified materials from the same place.
2.317 +
2.318 + e) Verify that the user has already received a copy of these
2.319 + materials or that you have already sent this user a copy.
2.320 +
2.321 + For an executable, the required form of the "work that uses the
2.322 +Library" must include any data and utility programs needed for
2.323 +reproducing the executable from it. However, as a special exception,
2.324 +the materials to be distributed need not include anything that is
2.325 +normally distributed (in either source or binary form) with the major
2.326 +components (compiler, kernel, and so on) of the operating system on
2.327 +which the executable runs, unless that component itself accompanies
2.328 +the executable.
2.329 +
2.330 + It may happen that this requirement contradicts the license
2.331 +restrictions of other proprietary libraries that do not normally
2.332 +accompany the operating system. Such a contradiction means you cannot
2.333 +use both them and the Library together in an executable that you
2.334 +distribute.
2.335 +
2.336 + 7. You may place library facilities that are a work based on the
2.337 +Library side-by-side in a single library together with other library
2.338 +facilities not covered by this License, and distribute such a combined
2.339 +library, provided that the separate distribution of the work based on
2.340 +the Library and of the other library facilities is otherwise
2.341 +permitted, and provided that you do these two things:
2.342 +
2.343 + a) Accompany the combined library with a copy of the same work
2.344 + based on the Library, uncombined with any other library
2.345 + facilities. This must be distributed under the terms of the
2.346 + Sections above.
2.347 +
2.348 + b) Give prominent notice with the combined library of the fact
2.349 + that part of it is a work based on the Library, and explaining
2.350 + where to find the accompanying uncombined form of the same work.
2.351 +
2.352 + 8. You may not copy, modify, sublicense, link with, or distribute
2.353 +the Library except as expressly provided under this License. Any
2.354 +attempt otherwise to copy, modify, sublicense, link with, or
2.355 +distribute the Library is void, and will automatically terminate your
2.356 +rights under this License. However, parties who have received copies,
2.357 +or rights, from you under this License will not have their licenses
2.358 +terminated so long as such parties remain in full compliance.
2.359 +
2.360 + 9. You are not required to accept this License, since you have not
2.361 +signed it. However, nothing else grants you permission to modify or
2.362 +distribute the Library or its derivative works. These actions are
2.363 +prohibited by law if you do not accept this License. Therefore, by
2.364 +modifying or distributing the Library (or any work based on the
2.365 +Library), you indicate your acceptance of this License to do so, and
2.366 +all its terms and conditions for copying, distributing or modifying
2.367 +the Library or works based on it.
2.368 +
2.369 + 10. Each time you redistribute the Library (or any work based on the
2.370 +Library), the recipient automatically receives a license from the
2.371 +original licensor to copy, distribute, link with or modify the Library
2.372 +subject to these terms and conditions. You may not impose any further
2.373 +restrictions on the recipients' exercise of the rights granted herein.
2.374 +You are not responsible for enforcing compliance by third parties with
2.375 +this License.
2.376 +
2.377 + 11. If, as a consequence of a court judgment or allegation of patent
2.378 +infringement or for any other reason (not limited to patent issues),
2.379 +conditions are imposed on you (whether by court order, agreement or
2.380 +otherwise) that contradict the conditions of this License, they do not
2.381 +excuse you from the conditions of this License. If you cannot
2.382 +distribute so as to satisfy simultaneously your obligations under this
2.383 +License and any other pertinent obligations, then as a consequence you
2.384 +may not distribute the Library at all. For example, if a patent
2.385 +license would not permit royalty-free redistribution of the Library by
2.386 +all those who receive copies directly or indirectly through you, then
2.387 +the only way you could satisfy both it and this License would be to
2.388 +refrain entirely from distribution of the Library.
2.389 +
2.390 +If any portion of this section is held invalid or unenforceable under any
2.391 +particular circumstance, the balance of the section is intended to apply,
2.392 +and the section as a whole is intended to apply in other circumstances.
2.393 +
2.394 +It is not the purpose of this section to induce you to infringe any
2.395 +patents or other property right claims or to contest validity of any
2.396 +such claims; this section has the sole purpose of protecting the
2.397 +integrity of the free software distribution system which is
2.398 +implemented by public license practices. Many people have made
2.399 +generous contributions to the wide range of software distributed
2.400 +through that system in reliance on consistent application of that
2.401 +system; it is up to the author/donor to decide if he or she is willing
2.402 +to distribute software through any other system and a licensee cannot
2.403 +impose that choice.
2.404 +
2.405 +This section is intended to make thoroughly clear what is believed to
2.406 +be a consequence of the rest of this License.
2.407 +
2.408 + 12. If the distribution and/or use of the Library is restricted in
2.409 +certain countries either by patents or by copyrighted interfaces, the
2.410 +original copyright holder who places the Library under this License may add
2.411 +an explicit geographical distribution limitation excluding those countries,
2.412 +so that distribution is permitted only in or among countries not thus
2.413 +excluded. In such case, this License incorporates the limitation as if
2.414 +written in the body of this License.
2.415 +
2.416 + 13. The Free Software Foundation may publish revised and/or new
2.417 +versions of the Lesser General Public License from time to time.
2.418 +Such new versions will be similar in spirit to the present version,
2.419 +but may differ in detail to address new problems or concerns.
2.420 +
2.421 +Each version is given a distinguishing version number. If the Library
2.422 +specifies a version number of this License which applies to it and
2.423 +"any later version", you have the option of following the terms and
2.424 +conditions either of that version or of any later version published by
2.425 +the Free Software Foundation. If the Library does not specify a
2.426 +license version number, you may choose any version ever published by
2.427 +the Free Software Foundation.
2.428 +
2.429 + 14. If you wish to incorporate parts of the Library into other free
2.430 +programs whose distribution conditions are incompatible with these,
2.431 +write to the author to ask for permission. For software which is
2.432 +copyrighted by the Free Software Foundation, write to the Free
2.433 +Software Foundation; we sometimes make exceptions for this. Our
2.434 +decision will be guided by the two goals of preserving the free status
2.435 +of all derivatives of our free software and of promoting the sharing
2.436 +and reuse of software generally.
2.437 +
2.438 + NO WARRANTY
2.439 +
2.440 + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
2.441 +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
2.442 +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
2.443 +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
2.444 +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
2.445 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2.446 +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
2.447 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
2.448 +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
2.449 +
2.450 + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
2.451 +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
2.452 +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
2.453 +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
2.454 +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
2.455 +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
2.456 +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
2.457 +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
2.458 +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
2.459 +DAMAGES.
2.460 +
2.461 + END OF TERMS AND CONDITIONS
2.462 +
2.463 + How to Apply These Terms to Your New Libraries
2.464 +
2.465 + If you develop a new library, and you want it to be of the greatest
2.466 +possible use to the public, we recommend making it free software that
2.467 +everyone can redistribute and change. You can do so by permitting
2.468 +redistribution under these terms (or, alternatively, under the terms of the
2.469 +ordinary General Public License).
2.470 +
2.471 + To apply these terms, attach the following notices to the library. It is
2.472 +safest to attach them to the start of each source file to most effectively
2.473 +convey the exclusion of warranty; and each file should have at least the
2.474 +"copyright" line and a pointer to where the full notice is found.
2.475 +
2.476 + <one line to give the library's name and a brief idea of what it does.>
2.477 + Copyright (C) <year> <name of author>
2.478 +
2.479 + This library is free software; you can redistribute it and/or
2.480 + modify it under the terms of the GNU Lesser General Public
2.481 + License as published by the Free Software Foundation; either
2.482 + version 2.1 of the License, or (at your option) any later version.
2.483 +
2.484 + This library is distributed in the hope that it will be useful,
2.485 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2.486 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2.487 + Lesser General Public License for more details.
2.488 +
2.489 + You should have received a copy of the GNU Lesser General Public
2.490 + License along with this library; if not, write to the Free Software
2.491 + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2.492 +
2.493 +Also add information on how to contact you by electronic and paper mail.
2.494 +
2.495 +You should also get your employer (if you work as a programmer) or your
2.496 +school, if any, to sign a "copyright disclaimer" for the library, if
2.497 +necessary. Here is a sample; alter the names:
2.498 +
2.499 + Yoyodyne, Inc., hereby disclaims all copyright interest in the
2.500 + library `Frob' (a library for tweaking knobs) written by James Random Hacker.
2.501 +
2.502 + <signature of Ty Coon>, 1 April 1990
2.503 + Ty Coon, President of Vice
2.504 +
2.505 +That's all there is to it!
2.506 +
2.507 +
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/gst-gmyth/ChangeLog Tue May 01 16:04:02 2007 +0100
3.3 @@ -0,0 +1,24 @@
3.4 +2006-08-17 Rosfran Borges <rosfran.borges@indt.org.br>
3.5 + * Added the correct gstreamer-base package (GSTBASE) at the configure.ac;
3.6 + GSTBASE_CFLAGS and GSTBASE_LIBS variables had the same values from
3.7 + the GST_CFLAGS/GST_LIBS.
3.8 +
3.9 +2006-08-16 Rosfran Borges <rosfran.borges@indt.org.br>
3.10 + * Fixed some installation issues, regarding lib-installing to the
3.11 + correct directory, and copying the header files to the destination
3.12 + dir (make install).
3.13 + * Put 'pkg-config' resource to the Maemo Myth library. The name of the
3.14 + PKG-CONFIG resource is 'maemo-myth', plus the minor and major version.
3.15 + Actually, the version is '0.1', so the library config file is:
3.16 + 'maemo-myth-0.1.pc'. You can type: 'pkg-config --cflags --libs
3.17 + maemo-myth-0.1'.
3.18 + * Many adjustments in the automake/autoconf configuration files
3.19 + (configure.ac, Makefile.am) - some autotools misusage fixed.
3.20 + * Added the MythURI structure, and the URI parsing utility functions
3.21 + (missing in the GLib).
3.22 + * Some functions were exported (myth_socket, mmyth_context), that's
3.23 + why many ther modules need to use them.
3.24 + * Fixed some library dependencies.
3.25 + * Prepared to be used inside the GStreamer (linking with the MythTV
3.26 + plug-in).
3.27 +
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/gst-gmyth/INSTALL Tue May 01 16:04:02 2007 +0100
4.3 @@ -0,0 +1,182 @@
4.4 +Basic Installation
4.5 +==================
4.6 +
4.7 + These are generic installation instructions.
4.8 +
4.9 + The `configure' shell script attempts to guess correct values for
4.10 +various system-dependent variables used during compilation. It uses
4.11 +those values to create a `Makefile' in each directory of the package.
4.12 +It may also create one or more `.h' files containing system-dependent
4.13 +definitions. Finally, it creates a shell script `config.status' that
4.14 +you can run in the future to recreate the current configuration, a file
4.15 +`config.cache' that saves the results of its tests to speed up
4.16 +reconfiguring, and a file `config.log' containing compiler output
4.17 +(useful mainly for debugging `configure').
4.18 +
4.19 + If you need to do unusual things to compile the package, please try
4.20 +to figure out how `configure' could check whether to do them, and mail
4.21 +diffs or instructions to the address given in the `README' so they can
4.22 +be considered for the next release. If at some point `config.cache'
4.23 +contains results you don't want to keep, you may remove or edit it.
4.24 +
4.25 + The file `configure.in' is used to create `configure' by a program
4.26 +called `autoconf'. You only need `configure.in' if you want to change
4.27 +it or regenerate `configure' using a newer version of `autoconf'.
4.28 +
4.29 +The simplest way to compile this package is:
4.30 +
4.31 + 1. `cd' to the directory containing the package's source code and type
4.32 + `./configure' to configure the package for your system. If you're
4.33 + using `csh' on an old version of System V, you might need to type
4.34 + `sh ./configure' instead to prevent `csh' from trying to execute
4.35 + `configure' itself.
4.36 +
4.37 + Running `configure' takes awhile. While running, it prints some
4.38 + messages telling which features it is checking for.
4.39 +
4.40 + 2. Type `make' to compile the package.
4.41 +
4.42 + 3. Optionally, type `make check' to run any self-tests that come with
4.43 + the package.
4.44 +
4.45 + 4. Type `make install' to install the programs and any data files and
4.46 + documentation.
4.47 +
4.48 + 5. You can remove the program binaries and object files from the
4.49 + source code directory by typing `make clean'. To also remove the
4.50 + files that `configure' created (so you can compile the package for
4.51 + a different kind of computer), type `make distclean'. There is
4.52 + also a `make maintainer-clean' target, but that is intended mainly
4.53 + for the package's developers. If you use it, you may have to get
4.54 + all sorts of other programs in order to regenerate files that came
4.55 + with the distribution.
4.56 +
4.57 +Compilers and Options
4.58 +=====================
4.59 +
4.60 + Some systems require unusual options for compilation or linking that
4.61 +the `configure' script does not know about. You can give `configure'
4.62 +initial values for variables by setting them in the environment. Using
4.63 +a Bourne-compatible shell, you can do that on the command line like
4.64 +this:
4.65 + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
4.66 +
4.67 +Or on systems that have the `env' program, you can do it like this:
4.68 + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
4.69 +
4.70 +Compiling For Multiple Architectures
4.71 +====================================
4.72 +
4.73 + You can compile the package for more than one kind of computer at the
4.74 +same time, by placing the object files for each architecture in their
4.75 +own directory. To do this, you must use a version of `make' that
4.76 +supports the `VPATH' variable, such as GNU `make'. `cd' to the
4.77 +directory where you want the object files and executables to go and run
4.78 +the `configure' script. `configure' automatically checks for the
4.79 +source code in the directory that `configure' is in and in `..'.
4.80 +
4.81 + If you have to use a `make' that does not supports the `VPATH'
4.82 +variable, you have to compile the package for one architecture at a time
4.83 +in the source code directory. After you have installed the package for
4.84 +one architecture, use `make distclean' before reconfiguring for another
4.85 +architecture.
4.86 +
4.87 +Installation Names
4.88 +==================
4.89 +
4.90 + By default, `make install' will install the package's files in
4.91 +`/usr/local/bin', `/usr/local/man', etc. You can specify an
4.92 +installation prefix other than `/usr/local' by giving `configure' the
4.93 +option `--prefix=PATH'.
4.94 +
4.95 + You can specify separate installation prefixes for
4.96 +architecture-specific files and architecture-independent files. If you
4.97 +give `configure' the option `--exec-prefix=PATH', the package will use
4.98 +PATH as the prefix for installing programs and libraries.
4.99 +Documentation and other data files will still use the regular prefix.
4.100 +
4.101 + In addition, if you use an unusual directory layout you can give
4.102 +options like `--bindir=PATH' to specify different values for particular
4.103 +kinds of files. Run `configure --help' for a list of the directories
4.104 +you can set and what kinds of files go in them.
4.105 +
4.106 + If the package supports it, you can cause programs to be installed
4.107 +with an extra prefix or suffix on their names by giving `configure' the
4.108 +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
4.109 +
4.110 +Optional Features
4.111 +=================
4.112 +
4.113 + Some packages pay attention to `--enable-FEATURE' options to
4.114 +`configure', where FEATURE indicates an optional part of the package.
4.115 +They may also pay attention to `--with-PACKAGE' options, where PACKAGE
4.116 +is something like `gnu-as' or `x' (for the X Window System). The
4.117 +`README' should mention any `--enable-' and `--with-' options that the
4.118 +package recognizes.
4.119 +
4.120 + For packages that use the X Window System, `configure' can usually
4.121 +find the X include and library files automatically, but if it doesn't,
4.122 +you can use the `configure' options `--x-includes=DIR' and
4.123 +`--x-libraries=DIR' to specify their locations.
4.124 +
4.125 +Specifying the System Type
4.126 +==========================
4.127 +
4.128 + There may be some features `configure' can not figure out
4.129 +automatically, but needs to determine by the type of host the package
4.130 +will run on. Usually `configure' can figure that out, but if it prints
4.131 +a message saying it can not guess the host type, give it the
4.132 +`--host=TYPE' option. TYPE can either be a short name for the system
4.133 +type, such as `sun4', or a canonical name with three fields:
4.134 + CPU-COMPANY-SYSTEM
4.135 +
4.136 +See the file `config.sub' for the possible values of each field. If
4.137 +`config.sub' isn't included in this package, then this package doesn't
4.138 +need to know the host type.
4.139 +
4.140 + If you are building compiler tools for cross-compiling, you can also
4.141 +use the `--target=TYPE' option to select the type of system they will
4.142 +produce code for and the `--build=TYPE' option to select the type of
4.143 +system on which you are compiling the package.
4.144 +
4.145 +Sharing Defaults
4.146 +================
4.147 +
4.148 + If you want to set default values for `configure' scripts to share,
4.149 +you can create a site shell script called `config.site' that gives
4.150 +default values for variables like `CC', `cache_file', and `prefix'.
4.151 +`configure' looks for `PREFIX/share/config.site' if it exists, then
4.152 +`PREFIX/etc/config.site' if it exists. Or, you can set the
4.153 +`CONFIG_SITE' environment variable to the location of the site script.
4.154 +A warning: not all `configure' scripts look for a site script.
4.155 +
4.156 +Operation Controls
4.157 +==================
4.158 +
4.159 + `configure' recognizes the following options to control how it
4.160 +operates.
4.161 +
4.162 +`--cache-file=FILE'
4.163 + Use and save the results of the tests in FILE instead of
4.164 + `./config.cache'. Set FILE to `/dev/null' to disable caching, for
4.165 + debugging `configure'.
4.166 +
4.167 +`--help'
4.168 + Print a summary of the options to `configure', and exit.
4.169 +
4.170 +`--quiet'
4.171 +`--silent'
4.172 +`-q'
4.173 + Do not print messages saying which checks are being made. To
4.174 + suppress all normal output, redirect it to `/dev/null' (any error
4.175 + messages will still be shown).
4.176 +
4.177 +`--srcdir=DIR'
4.178 + Look for the package's source code in directory DIR. Usually
4.179 + `configure' can determine that directory automatically.
4.180 +
4.181 +`--version'
4.182 + Print the version of Autoconf used to generate the `configure'
4.183 + script, and exit.
4.184 +
4.185 +`configure' also accepts some other, not widely useful, options.
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/gst-gmyth/Makefile.am Tue May 01 16:04:02 2007 +0100
5.3 @@ -0,0 +1,3 @@
5.4 +SUBDIRS = mythtvsrc nuvdemux
5.5 +
5.6 +DIST_SUBDIRS = mythtvsrc nuvdemux
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/gst-gmyth/autogen.sh Tue May 01 16:04:02 2007 +0100
6.3 @@ -0,0 +1,101 @@
6.4 +#!/bin/sh
6.5 +# Run this to generate all the initial makefiles, etc.
6.6 +
6.7 +DIE=0
6.8 +package=mythtvsrc
6.9 +srcfile=configure.ac
6.10 +
6.11 +# a quick cvs co if necessary to alleviate the pain - may remove this
6.12 +# when developers get a clue ;)
6.13 +if test ! -d common;
6.14 +then
6.15 + echo "+ getting common/ from svn"
6.16 + svn co common
6.17 +fi
6.18 +
6.19 +# source helper functions
6.20 +if test ! -f common/autogen-helper.sh;
6.21 +then
6.22 + echo There is something wrong with your source tree.
6.23 + echo You are missing common/autogen-helper.sh
6.24 + exit 1
6.25 +fi
6.26 +. common/autogen-helper.sh
6.27 +
6.28 +CONFIGURE_DEF_OPT='--enable-maintainer-mode'
6.29 +
6.30 +CONFIGURE_EXT_OPT="$@"
6.31 +
6.32 +autogen_options
6.33 +
6.34 +echo -n "+ check for build tools"
6.35 +if test ! -z "$NOCHECK"; then echo " skipped"; else echo; fi
6.36 +version_check "autoconf" "$AUTOCONF autoconf autoconf-2.54 autoconf-2.53" \
6.37 + "ftp://ftp.gnu.org/pub/gnu/autoconf/" 2 53 || DIE=1
6.38 +version_check "automake" "$AUTOMAKE automake automake-1.9 automake-1.8 automake-1.7 automake-1.6" \
6.39 + "ftp://ftp.gnu.org/pub/gnu/automake/" 1 6 || DIE=1
6.40 +version_check "libtoolize" "$LIBTOOLIZE libtoolize" \
6.41 + "ftp://ftp.gnu.org/pub/gnu/libtool/" 1 5 0 || DIE=1
6.42 +version_check "pkg-config" "" \
6.43 + "http://www.freedesktop.org/software/pkgconfig" 0 8 0 || DIE=1
6.44 +
6.45 +die_check $DIE
6.46 +
6.47 +aclocal_check || DIE=1
6.48 +autoheader_check || DIE=1
6.49 +
6.50 +die_check $DIE
6.51 +
6.52 +# if no arguments specified then this will be printed
6.53 +if test -z "$*"; then
6.54 + echo "+ checking for autogen.sh options"
6.55 + echo " This autogen script will automatically run ./configure as:"
6.56 + echo " ./configure $CONFIGURE_DEF_OPT"
6.57 + echo " To pass any additional options, please specify them on the $0"
6.58 + echo " command line."
6.59 +fi
6.60 +
6.61 +toplevel_check $srcfile
6.62 +
6.63 +tool_run "$aclocal" "-I m4 $ACLOCAL_FLAGS"
6.64 +tool_run "$libtoolize" "--copy --force"
6.65 +tool_run "$autoheader"
6.66 +
6.67 +# touch the stamp-h.in build stamp so we don't re-run autoheader in maintainer mode -- wingo
6.68 +echo timestamp > stamp-h.in 2> /dev/null
6.69 +
6.70 +tool_run "$autoconf"
6.71 +tool_run "$automake" "-a -c"
6.72 +
6.73 +# if enable exists, add an -enable option for each of the lines in that file
6.74 +if test -f enable; then
6.75 + for a in `cat enable`; do
6.76 + CONFIGURE_FILE_OPT="--enable-$a"
6.77 + done
6.78 +fi
6.79 +
6.80 +# if disable exists, add an -disable option for each of the lines in that file
6.81 +if test -f disable; then
6.82 + for a in `cat disable`; do
6.83 + CONFIGURE_FILE_OPT="$CONFIGURE_FILE_OPT --disable-$a"
6.84 + done
6.85 +fi
6.86 +
6.87 +test -n "$NOCONFIGURE" && {
6.88 + echo "+ skipping configure stage for package $package, as requested."
6.89 + echo "+ autogen.sh done."
6.90 + exit 0
6.91 +}
6.92 +
6.93 +echo "+ running configure ... "
6.94 +test ! -z "$CONFIGURE_DEF_OPT" && echo " ./configure default flags: $CONFIGURE_DEF_OPT"
6.95 +test ! -z "$CONFIGURE_EXT_OPT" && echo " ./configure external flags: $CONFIGURE_EXT_OPT"
6.96 +test ! -z "$CONFIGURE_FILE_OPT" && echo " ./configure enable/disable flags: $CONFIGURE_FILE_OPT"
6.97 +echo
6.98 +
6.99 +./configure $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT $CONFIGURE_FILE_OPT || {
6.100 + echo " configure failed"
6.101 + exit 1
6.102 +}
6.103 +
6.104 +echo "Now type 'make' to compile $package."
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/gst-gmyth/configure.ac Tue May 01 16:04:02 2007 +0100
7.3 @@ -0,0 +1,172 @@
7.4 +# -*- Autoconf -*-
7.5 +# Process this file with autoconf to produce a configure script.
7.6 +
7.7 +AC_PREREQ(2.50)
7.8 +
7.9 +AC_INIT([mythtvsrc],[0.1])
7.10 +
7.11 +dnl AC_CONFIG_SRCDIR([src])
7.12 +AC_CONFIG_HEADER(config.h)
7.13 +
7.14 +dnl when going to/from release please set the nano (fourth number) right !
7.15 +dnl releases only do Wall, SVN and prerelease does Werror too
7.16 +AS_VERSION(mythtvsrc, MYTHTVSRC, 0, 1, 0, 3, MYTHTVSRC_SVN="no", MYTHTVSRC_SVN="yes")
7.17 +
7.18 +MYTHTVSRC_MAJORMINOR=$MYTHTVSRC_MAJOR_VERSION.$MYTHTVSRC_MINOR_VERSION
7.19 +
7.20 +AC_SUBST(MYTHTVSRC_MAJORMINOR)
7.21 +
7.22 +dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode
7.23 +AM_MAINTAINER_MODE
7.24 +dnl make aclocal work in maintainer mode
7.25 +AC_SUBST(ACLOCAL_AMFLAGS, "-I m4")
7.26 +
7.27 +# Checks for programs.
7.28 +# check for tools
7.29 +# Make sure CFLAGS is defined to stop AC_PROC_CC adding -g
7.30 +CFLAGS="$CFLAGS -Wall"
7.31 +AC_PROG_CC
7.32 +AC_PROG_LIBTOOL
7.33 +# Checks for libraries.
7.34 +
7.35 +# Checks for header files.
7.36 +AC_HEADER_STDC
7.37 +AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h unistd.h])
7.38 +
7.39 +# Checks for typedefs, structures, and compiler characteristics.
7.40 +AC_C_CONST
7.41 +AC_TYPE_PID_T
7.42 +AC_STRUCT_TM
7.43 +
7.44 +# Checks for library functions.
7.45 +AC_FUNC_FORK
7.46 +AC_PROG_GCC_TRADITIONAL
7.47 +AC_FUNC_MALLOC
7.48 +AC_FUNC_MKTIME
7.49 +AC_FUNC_VPRINTF
7.50 +AC_CHECK_FUNCS([memset socket stime strstr strtoul])
7.51 +
7.52 +AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
7.53 +
7.54 +# Checks required packages
7.55 +
7.56 +dnl Test if --disable-debug given
7.57 +AC_ARG_ENABLE(debug,
7.58 + [AC_HELP_STRING([--disable-debug], [disable debugging mode])],
7.59 + enable_debug="$enableval",
7.60 + enable_debug=yes)
7.61 +
7.62 +if test "x$enable_debug" = "xyes" ; then
7.63 + CFLAGS="$CFLAGS -g"
7.64 +else
7.65 + AC_DEFINE( NDEBUG, 1, [disable debug messages] )
7.66 + CFLAGS="$CFLAGS -O2 -DG_DISABLE_CHECKS -DNDEBUG"
7.67 +fi
7.68 +
7.69 +AM_CONDITIONAL( NDEBUG, test "x$enable_debug" = "xyes" )
7.70 +
7.71 +# Check for pkgconfig
7.72 +AC_CHECK_PROG(HAVE_PKGCONFIG, pkg-config, yes, no)
7.73 +# Give error and exit if we don't have pkgconfig
7.74 +if test "x$HAVE_PKGCONFIG" = "xno"; then
7.75 + AC_MSG_ERROR(you need to have pkgconfig installed !)
7.76 +fi
7.77 +
7.78 +# Check for Glib2.0
7.79 +PKG_CHECK_MODULES(GLIB, glib-2.0, HAVE_GLIB=yes,HAVE_GLIB=no)
7.80 +
7.81 +# Give error and exit if we don't have glib
7.82 +if test "x$HAVE_GLIB" = "xno"; then
7.83 + AC_MSG_ERROR(you need glib-2.0 installed)
7.84 +fi
7.85 +
7.86 +# make GLIB_CFLAGS and GLIB_LIBS available
7.87 +AC_SUBST(GLIB_CFLAGS)
7.88 +AC_SUBST(GLIB_LIBS)
7.89 +
7.90 +# Check for GObject2.0
7.91 +PKG_CHECK_MODULES(GOBJECT,
7.92 + gobject-2.0,
7.93 + HAVE_GOBJECT=yes, HAVE_GOBJECT=no)
7.94 +
7.95 +# Give error and exit if we don't have gobject
7.96 +if test "x$HAVE_GOBJECT" = "xno"; then
7.97 + AC_MSG_ERROR(you need gobject-2.0 installed)
7.98 +fi
7.99 +
7.100 +# make GOBJECT_CFLAGS and GOBJECT_LIBS available
7.101 +AC_SUBST(GOBJECT_CFLAGS)
7.102 +AC_SUBST(GOBJECT_LIBS)
7.103 +
7.104 +dnl *** MythTV ***
7.105 +PKG_CHECK_MODULES(GMYTH,
7.106 + gmyth,
7.107 + HAVE_GMYTH=yes, HAVE_GMYTH=no)
7.108 +
7.109 +# Give error and exit if we don't have gobject
7.110 +if test "x$HAVE_GMYTH" = "xno"; then
7.111 + AC_MSG_ERROR(you need gmyth must to be installed)
7.112 +fi
7.113 +
7.114 +# make GMYTH_CFLAGS and GMYTH_LIBS available
7.115 +AC_SUBST(GMYTH_CFLAGS)
7.116 +AC_SUBST(GMYTH_LIBS)
7.117 +
7.118 +# GStreamer version required
7.119 +GST_REQUIRED=0.10
7.120 +GST_MAJORMINOR=0.10
7.121 +
7.122 +GST_PLUGINS_DIR=`$PKG_CONFIG gstreamer-plugins-base-$GST_MAJORMINOR --variable pluginsdir`
7.123 +AC_SUBST(GST_PLUGINS_DIR)
7.124 +AC_MSG_NOTICE(Using GStreamer Base Plugins in $GST_PLUGINS_DIR)
7.125 +
7.126 +dnl this really should only contain flags, not libs - they get added before
7.127 +dnl whatevertarget_LIBS and -L flags here affect the rest of the linking
7.128 +GST_PLUGIN_LDFLAGS="-module -avoid-version $GST_PLUGINS_DIR"
7.129 +AC_SUBST(GST_PLUGIN_LDFLAGS)
7.130 +
7.131 +# check for gstreamer development files
7.132 +PKG_CHECK_MODULES(GST, \
7.133 + gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED,
7.134 + HAVE_GST=yes, HAVE_GST=no)
7.135 +
7.136 +# Give error and exit if we don't have gstreamer
7.137 +if test "x$HAVE_GST" = "xno"; then
7.138 + AC_MSG_ERROR(you need gstreamer development packages installed !)
7.139 +fi
7.140 +
7.141 +# make GST_CFLAGS and GST_LIBS available
7.142 +AC_SUBST(GST_CFLAGS)
7.143 +AC_SUBST(GST_LIBS)
7.144 +
7.145 +# check for gstreamer-base plugins (xoverlay interface)
7.146 +GST_BASE_REQUIRED=0.10
7.147 +GST_BASE_MAJORMINOR=0.10
7.148 +PKG_CHECK_MODULES(GST_BASE, \
7.149 + gstreamer-base-$GST_BASE_MAJORMINOR >= $GST_BASE_REQUIRED,
7.150 + HAVE_GST_BASE=yes, HAVE_GST_BASE=no)
7.151 +
7.152 +# Give error and exit if we don't have gstreamer base libraries
7.153 +if test "x$HAVE_GST_BASE" = "xno"; then
7.154 + AC_MSG_ERROR(you need gstreamer base development packages installed !)
7.155 +fi
7.156 +
7.157 +# make GST_BASE_CFLAGS and GST_BASE_LIBS available
7.158 +AC_SUBST(GST_BASE_CFLAGS)
7.159 +AC_SUBST(GST_BASE_LIBS)
7.160 +
7.161 +# make GST_MAJORMINOR available in Makefile.am
7.162 +AC_SUBST(GST_MAJORMINOR)
7.163 +
7.164 +AC_DEFINE(GST_LICENSE, "LGPL", [License for Distribution])
7.165 +
7.166 +AC_DEFINE(GST_PACKAGE_NAME, "GStreamer", [Gstremar package name])
7.167 +
7.168 +AC_DEFINE(GST_PACKAGE_ORIGIN, "http://gstreamer.net/", [Origin of this package] )
7.169 +
7.170 +AC_CONFIG_FILES([
7.171 +Makefile
7.172 +src/Makefile
7.173 +])
7.174 +
7.175 +AC_OUTPUT
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/gst-gmyth/debian/changelog Tue May 01 16:04:02 2007 +0100
8.3 @@ -0,0 +1,6 @@
8.4 +gst-indt-plugins (0.10.2.debian-1) unstable; urgency=low
8.5 +
8.6 + * Initial packaged;
8.7 +
8.8 + -- Renato Araujo Oliveira Filho <renato.filho@indt.org.br> Thu, 09 Nov 2006 15:58:00 -0300
8.9 +
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/gst-gmyth/debian/compat Tue May 01 16:04:02 2007 +0100
9.3 @@ -0,0 +1,1 @@
9.4 +4
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/gst-gmyth/debian/control Tue May 01 16:04:02 2007 +0100
10.3 @@ -0,0 +1,27 @@
10.4 +Source: gst-indt-plugins
10.5 +Section: libs
10.6 +Priority: optional
10.7 +Maintainer: Renato Araujo Oliveira Filho <renato.filho@indt.org.br>
10.8 +Build-Depends: debhelper (>= 4.1.0), cdbs (>= 0.4.8), autotools-dev, pkg-config (>= 0.11.0), libgstreamer0.10-dev (>= 0.10.0), gmyth-dev (>= 0.3)
10.9 +Standards-Version: 3.6.2
10.10 +
10.11 +Package: gstreamer0.10-indt-nuvdemux
10.12 +Architecture: any
10.13 +Section: libs
10.14 +Depends: ${misc:Depends}, ${shlibs:Depends}
10.15 +Description: INdT nuv demux GStreamer plugin
10.16 + This GStreamer plugin permits demux of Nuv streams.
10.17 +
10.18 +Package: gstreamer0.10-indt-mythtvsrc
10.19 +Architecture: any
10.20 +Section: libs
10.21 +Depends: ${misc:Depends}, ${shlibs:Depends}, gmyth (>= 0.3)
10.22 +Description: INdT mythtv source GStreamer plugin
10.23 + This GStreamer plugin permits read streamer from MythTv Server
10.24 +
10.25 +Package: maemo-nuvdemux
10.26 +Architecture: all
10.27 +Depends: gstreamer0.10-indt-nuvdemux
10.28 +Description: enable support to nuvdemux on osso media server (meta-package)
10.29 + This package is a meta-package that, when installed, guarantees that you
10.30 + have support to nuv files on osso-media-server.
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/gst-gmyth/debian/copyright Tue May 01 16:04:02 2007 +0100
11.3 @@ -0,0 +1,23 @@
11.4 +This package was debianized by Renato Araujo Oliveira Filho <renato.filho@indt.org.br> on
11.5 +Thu, 09 Nov 2006 15:58:00 -0300.
11.6 +
11.7 +Copyright Holder: 2006 INdT
11.8 +
11.9 +License:
11.10 +
11.11 + This package is free software; you can redistribute it and/or modify
11.12 + it under the terms of the GNU General Public License as published by
11.13 + the Free Software Foundation; version 2 dated June, 1991.
11.14 +
11.15 + This package is distributed in the hope that it will be useful,
11.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
11.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.18 + GNU General Public License for more details.
11.19 +
11.20 + You should have received a copy of the GNU General Public License
11.21 + along with this package; if not, write to the Free Software
11.22 + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
11.23 + MA 02110-1301, USA.
11.24 +
11.25 +On Debian systems, the complete text of the GNU General
11.26 +Public License can be found in `/usr/share/common-licenses/GPL'.
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/gst-gmyth/debian/gstreamer0.10-indt-mythtvsrc.install Tue May 01 16:04:02 2007 +0100
12.3 @@ -0,0 +1,1 @@
12.4 +debian/tmp/usr/lib/gstreamer-*/*mythtvsrc*.so
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/gst-gmyth/debian/gstreamer0.10-indt-nuvdemux.install Tue May 01 16:04:02 2007 +0100
13.3 @@ -0,0 +1,1 @@
13.4 +debian/tmp/usr/lib/gstreamer-*/*nuvdemux*.so
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/gst-gmyth/debian/maemo-nuvdemux.install Tue May 01 16:04:02 2007 +0100
14.3 @@ -0,0 +1,2 @@
14.4 +debian/nuv.xml usr/share/mime/packages/
14.5 +debian/osso_media_server_nuv.schemas usr/share/gconf/schemas
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/gst-gmyth/debian/maemo-nuvdemux.postinst Tue May 01 16:04:02 2007 +0100
15.3 @@ -0,0 +1,24 @@
15.4 +#! /bin/sh
15.5 +set -e
15.6 +
15.7 +#DEBHELPER#
15.8 +
15.9 +# Register our X Desktop Group Shared MIME-info Database info
15.10 +if [ -x /usr/bin/update-mime-database ] ; then
15.11 + /usr/bin/update-mime-database /usr/share/mime
15.12 +fi
15.13 +
15.14 +# Register a new type on Osso Media Server
15.15 +if [ -x /usr/bin/gconftool-2 ] ; then
15.16 + /usr/bin/gconftool-2 --makefile-install-rule /usr/share/gconf/schemas/osso_media_server_nuv.schemas
15.17 +fi
15.18 +
15.19 +#append nuv info on osso mediaplayer ui
15.20 +data_file=/usr/share/applications/hildon/mp_ui.desktop
15.21 +tmp_file=/tmp/mp_ui.desktop
15.22 +cat $data_file | sed 's/X-Osso-URI-Actions=rtsp/X-Osso-URI-Actions=rtsp;myth/' | sed 's/MimeType=\(.*\)/MimeType=\1;video\/x-nuv/' > $tmp_file
15.23 +echo -e "\n\n[X-Osso-URI-Action Handler myth] \nMethod=mime_open\nName=medi_ap_mediaplayer_name\nTranslationDomain=mediaplayer" >> $tmp_file
15.24 +cat $tmp_file > $data_file
15.25 +echo "FILE DESKTOP UPDATED"
15.26 +
15.27 +exit 0
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/gst-gmyth/debian/nuv.xml Tue May 01 16:04:02 2007 +0100
16.3 @@ -0,0 +1,13 @@
16.4 +<?xml version="1.0" encoding="UTF-8"?>
16.5 +<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info"
16.6 + xmlns:osso="http://nokia.com/osso/mime-categories">
16.7 + <mime-type type="video/x-nuv">
16.8 + <comment>Nuv File</comment>
16.9 + <comment xml:lang="en">Mythtv Nuv file container</comment>
16.10 + <magic priority="60">
16.11 + <match value="MythTVVideo" type="string" offset="0"/>
16.12 + </magic>
16.13 + <glob pattern="*.nuv"/>
16.14 + <osso:category name="video"/>
16.15 + </mime-type>
16.16 +</mime-info>
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/gst-gmyth/debian/osso_media_server_nuv.schemas Tue May 01 16:04:02 2007 +0100
17.3 @@ -0,0 +1,16 @@
17.4 +<?xml version="1.0"?>
17.5 +<gconfschemafile>
17.6 + <schemalist>
17.7 + <schema>
17.8 + <key>/schemas/apps/osso/osso_media_server/demux_video/video_x-nuv</key>
17.9 + <applyto>/apps/osso/osso_media_server/demux_video/video_x-nuv</applyto>
17.10 + <owner>osso_media_server</owner>
17.11 + <type>list</type>
17.12 + <list_type>string</list_type>
17.13 + <default>[video/x-nuv,nuvdemux]</default>
17.14 + <locale name="C">
17.15 + <short>Play MYTHTV .nuv files.</short>
17.16 + </locale>
17.17 + </schema>
17.18 + </schemalist>
17.19 +</gconfschemafile>
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/gst-gmyth/debian/rules Tue May 01 16:04:02 2007 +0100
18.3 @@ -0,0 +1,19 @@
18.4 +#!/usr/bin/make -f
18.5 +
18.6 +include /usr/share/cdbs/1/rules/debhelper.mk
18.7 +include /usr/share/cdbs/1/rules/simple-patchsys.mk
18.8 +include /usr/share/cdbs/1/class/gnome.mk
18.9 +include /usr/share/cdbs/1/rules/utils.mk
18.10 +
18.11 +# debian package version
18.12 +version=$(shell dpkg-parsechangelog | grep ^Version: | cut -d ' ' -f 2)
18.13 +
18.14 +maint: debian/control
18.15 +
18.16 +binary-install/gstreamer0.10-indt-nuvdemux::
18.17 + rm -f debian/gstreamer0.10-indt-nuvdemux/usr/lib/gstreamer-0.10/libgstnuvdemux.la
18.18 + rm -f debian/gstreamer0.10-indt-nuvdemux/usr/lib/gstreamer-0.10/libgstnuvdemux.a
18.19 + rm -f debian/gstreamer0.10-indt-nuvdemux/usr/lib/gstreamer-0.10/libgsttypefindfunctions_indt.la
18.20 + rm -f debian/gstreamer0.10-indt-nuvdemux/usr/lib/gstreamer-0.10/libgsttypefindfunctions_indt.a
18.21 +
18.22 +.PHONY: maint
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/gst-gmyth/mythsrc/Makefile.am Tue May 01 16:04:02 2007 +0100
19.3 @@ -0,0 +1,23 @@
19.4 +plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
19.5 +
19.6 +plugin_LTLIBRARIES = libgstmythtvsrc.la
19.7 +
19.8 +libgstmythtvsrc_la_SOURCES = \
19.9 + gstmythtvsrc.c
19.10 +
19.11 +libgstmythtvsrc_la_CFLAGS = \
19.12 + $(GST_CFLAGS) \
19.13 + $(GST_BASE_CFLAGS) \
19.14 + $(GMYTH_CFLAGS)
19.15 +
19.16 +libgstmythtvsrc_la_LDFLAGS = \
19.17 + $(GST_PLUGIN_LDFLAGS)
19.18 +
19.19 +libgstmythtvsrc_la_LIBADD = \
19.20 + $(GST_LIBS) \
19.21 + $(GST_BASE_LIBS) \
19.22 + $(GMYTH_LIBS)
19.23 +
19.24 +noinst_HEADERS = \
19.25 + gstmythtvsrc.h
19.26 +
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/gst-gmyth/mythsrc/gstmythtvsrc.c Tue May 01 16:04:02 2007 +0100
20.3 @@ -0,0 +1,1259 @@
20.4 +/* GStreamer MythTV Plug-in
20.5 + * Copyright (C) <2006> Rosfran Borges <rosfran.borges@indt.org.br>
20.6 + *
20.7 + * This library is free software; you can redistribute it and/or
20.8 + * modify it under the terms of the GNU Library General Public
20.9 + * License as published by the Free Software Foundation; either
20.10 + * version 2 of the License, or (at your option) any later version.
20.11 + *
20.12 + * This library is distributed in the hope that it will be useful,
20.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
20.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20.15 + * Library General Public License for more details.
20.16 + *
20.17 + * You should have received a copy of the GNU Library General Public
20.18 + * License along with this library; if not, write to the
20.19 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20.20 + * Boston, MA 02111-1307, USA.
20.21 + */
20.22 +/**
20.23 + * SECTION:element-mythtvsrc
20.24 + *
20.25 + * <refsect2>
20.26 + * <para>
20.27 + * MythTVSrc allows to access a remote MythTV backend streaming Video/Audio server,
20.28 + * and to render audio and video content through a TCP/IP connection to a specific
20.29 + * port on this server, and based on a known MythTV protocol that is based on
20.30 + * some message passing, such as REQUEST_BLOCK on a specified number of bytes, to get
20.31 + * some chunk of remote file data.
20.32 + * You should pass the information aboute the remote MythTV backend server
20.33 + * through the <link linkend="GstMythTVSrc--location">location</link> property.
20.34 + * </para>
20.35 + * <title>Examples</title>
20.36 + * <para>
20.37 + * If you want to get the LiveTV content (set channel, TV tuner, RemoteEncoder,
20.38 + * Recorder),
20.39 + * put the following URI:
20.40 + *
20.41 + * <programlisting>
20.42 + * myth://xxx.xxx.xxx.xxx:6543/livetv?channel=BBC
20.43 + * </programlisting>
20.44 + *
20.45 + * This URI will say to the gmyth library to configure the Recorder instance (used to
20.46 + * change the channel, start the TV multimedia content transmition, etc.), using
20.47 + * the IP address (xxx.xxx.xxx.xxx) and port number (6543) of the MythTV backend
20.48 + * server, and setting the channel name to "BBC".
20.49 + *
20.50 + * To get a already recorded the MythTV NUV file, put the following URI:
20.51 + *
20.52 + * <programlisting>
20.53 + * myth://xxx.xxx.xxx.xxx:6543/filename.nuv
20.54 + * </programlisting>
20.55 + *
20.56 + * This URI will say to the gmyth library to configure the Recorder instance (used to
20.57 + * change the channel, start the TV multimedia content transmition, etc.), using
20.58 + * the IP address (xxx.xxx.xxx.xxx) and port number (6543) of the MythTV backend
20.59 + * server, and setting the channel name to "BBC".
20.60 + *
20.61 + * Another possible way to use the LiveTV content, and just in the case you want to
20.62 + * use the mysql database, put the location URI in the following format:
20.63 + *
20.64 + * <programlisting>
20.65 + * myth://mythtv:mythtv@xxx.xxx.xxx.xxx:6543/?mythconverg&channel=9
20.66 + * </programlisting>
20.67 + *
20.68 + * Where the first field is the protocol (myth), the second and third are user
20.69 + * name (mythtv) and password (mythtv), then backend host name and port number,
20.70 + * and the last field is the database name (mythconverg).
20.71 + * </para>
20.72 + * </refsect2>
20.73 + */
20.74 +#ifdef HAVE_CONFIG_H
20.75 +#include "config.h"
20.76 +#endif
20.77 +
20.78 +#include "gstmythtvsrc.h"
20.79 +#include <gmyth/gmyth_file.h>
20.80 +#include <gmyth/gmyth_file_transfer.h>
20.81 +#include <gmyth/gmyth_file_local.h>
20.82 +#include <gmyth/gmyth_livetv.h>
20.83 +
20.84 +#include <gmyth/gmyth_socket.h>
20.85 +#include <gmyth/gmyth_tvchain.h>
20.86 +
20.87 +#include <string.h>
20.88 +#include <unistd.h>
20.89 +
20.90 +GST_DEBUG_CATEGORY_STATIC (mythtvsrc_debug);
20.91 +#define GST_CAT_DEFAULT mythtvsrc_debug
20.92 +
20.93 +#define GST_GMYTHTV_ID_NUM 1
20.94 +
20.95 +#define GST_GMYTHTV_CHANNEL_DEFAULT_NUM (-1)
20.96 +
20.97 +#define GMYTHTV_VERSION_DEFAULT 30
20.98 +
20.99 +#define GMYTHTV_TRANSFER_MAX_WAITS 100
20.100 +
20.101 +#define GMYTHTV_TRANSFER_MAX_RESENDS 2
20.102 +
20.103 +#define GMYTHTV_TRANSFER_MAX_BUFFER (128*1024)
20.104 +
20.105 +#define MAX_READ_SIZE (4*1024)
20.106 +
20.107 +#define GST_FLOW_ERROR_NO_DATA (-101)
20.108 +
20.109 +#define REQUEST_MAX_SIZE (64*1024)
20.110 +
20.111 +#define INTERNAL_BUFFER_SIZE (90*1024)
20.112 +
20.113 +static const GstElementDetails gst_mythtv_src_details =
20.114 +GST_ELEMENT_DETAILS ("MythTV client source",
20.115 + "Source/Network",
20.116 + "Control and receive data as a client over the network "
20.117 + "via raw socket connections using the MythTV protocol",
20.118 + "Rosfran Borges <rosfran.borges@indt.org.br>");
20.119 +
20.120 +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
20.121 + GST_PAD_SRC,
20.122 + GST_PAD_ALWAYS,
20.123 + GST_STATIC_CAPS ("video/x-nuv"));
20.124 +
20.125 +enum
20.126 +{
20.127 + PROP_0,
20.128 + PROP_LOCATION,
20.129 +#ifndef GST_DISABLE_GST_DEBUG
20.130 + PROP_GMYTHTV_DBG,
20.131 +#endif
20.132 + PROP_GMYTHTV_VERSION,
20.133 + PROP_GMYTHTV_LIVE,
20.134 + PROP_GMYTHTV_LIVEID,
20.135 + PROP_GMYTHTV_LIVE_CHAINID,
20.136 + PROP_GMYTHTV_ENABLE_TIMING_POSITION,
20.137 + PROP_GMYTHTV_CHANNEL_NUM,
20.138 + PROP_GMYTHTV_MAX_TRY
20.139 +};
20.140 +
20.141 +static void gst_mythtv_src_clear (GstMythtvSrc *mythtv_src);
20.142 +
20.143 +static void gst_mythtv_src_finalize (GObject * gobject);
20.144 +
20.145 +static GstFlowReturn gst_mythtv_src_create (GstPushSrc * psrc,
20.146 + GstBuffer ** outbuf);
20.147 +
20.148 +static gboolean gst_mythtv_src_start (GstBaseSrc * bsrc);
20.149 +static gboolean gst_mythtv_src_stop (GstBaseSrc * bsrc);
20.150 +static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size);
20.151 +static gboolean gst_mythtv_src_is_seekable (GstBaseSrc * push_src);
20.152 +
20.153 +static gboolean gst_mythtv_src_do_seek (GstBaseSrc * base,
20.154 + GstSegment * segment);
20.155 +
20.156 +static GstStateChangeReturn
20.157 +gst_mythtv_src_change_state (GstElement * element, GstStateChange transition);
20.158 +
20.159 +static void gst_mythtv_src_set_property (GObject * object, guint prop_id,
20.160 + const GValue * value, GParamSpec * pspec);
20.161 +static void gst_mythtv_src_get_property (GObject * object, guint prop_id,
20.162 + GValue * value, GParamSpec * pspec);
20.163 +
20.164 +static void gst_mythtv_src_uri_handler_init (gpointer g_iface,
20.165 + gpointer iface_data);
20.166 +
20.167 +static gboolean gst_mythtv_src_handle_query (GstPad * pad, GstQuery * query);
20.168 +
20.169 +static gboolean gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
20.170 +
20.171 +static GMythFileReadResult do_read_request_response (GstMythtvSrc * src, guint size,
20.172 + GByteArray * data_ptr);
20.173 +
20.174 +static void
20.175 +_urihandler_init (GType type)
20.176 +{
20.177 + static const GInterfaceInfo urihandler_info = {
20.178 + gst_mythtv_src_uri_handler_init,
20.179 + NULL,
20.180 + NULL
20.181 + };
20.182 +
20.183 + g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
20.184 +
20.185 + GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0, "MythTV src");
20.186 +}
20.187 +
20.188 +GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstPushSrc,
20.189 + GST_TYPE_PUSH_SRC, _urihandler_init)
20.190 +
20.191 + static void gst_mythtv_src_base_init (gpointer g_class)
20.192 +{
20.193 + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
20.194 +
20.195 + gst_element_class_add_pad_template (element_class,
20.196 + gst_static_pad_template_get (&srctemplate));
20.197 +
20.198 + gst_element_class_set_details (element_class, &gst_mythtv_src_details);
20.199 +
20.200 + element_class->change_state = gst_mythtv_src_change_state;
20.201 +
20.202 +}
20.203 +
20.204 +static void
20.205 +gst_mythtv_src_class_init (GstMythtvSrcClass * klass)
20.206 +{
20.207 + GObjectClass *gobject_class;
20.208 + GstPushSrcClass *gstpushsrc_class;
20.209 + GstBaseSrcClass *gstbasesrc_class;
20.210 +
20.211 + gobject_class = (GObjectClass *) klass;
20.212 + gstbasesrc_class = (GstBaseSrcClass *) klass;
20.213 + gstpushsrc_class = (GstPushSrcClass *) klass;
20.214 +
20.215 + gobject_class->set_property = gst_mythtv_src_set_property;
20.216 + gobject_class->get_property = gst_mythtv_src_get_property;
20.217 + gobject_class->finalize = gst_mythtv_src_finalize;
20.218 +
20.219 + g_object_class_install_property
20.220 + (gobject_class, PROP_LOCATION,
20.221 + g_param_spec_string ("location", "Location",
20.222 + "The location. In the form:"
20.223 + "\n\t\t\tmyth://a.com/file.nuv"
20.224 + "\n\t\t\tmyth://a.com:23223/file.nuv "
20.225 + "\n\t\t\ta.com/file.nuv - default scheme 'myth'",
20.226 + "", G_PARAM_READWRITE));
20.227 +
20.228 + g_object_class_install_property
20.229 + (gobject_class, PROP_GMYTHTV_VERSION,
20.230 + g_param_spec_int ("mythtv-version", "mythtv-version",
20.231 + "Change MythTV version", 26, 30, 26, G_PARAM_READWRITE));
20.232 +
20.233 + g_object_class_install_property
20.234 + (gobject_class, PROP_GMYTHTV_LIVEID,
20.235 + g_param_spec_int ("mythtv-live-id", "mythtv-live-id",
20.236 + "Change MythTV version",
20.237 + 0, 200, GST_GMYTHTV_ID_NUM, G_PARAM_READWRITE));
20.238 +
20.239 + g_object_class_install_property
20.240 + (gobject_class, PROP_GMYTHTV_LIVE_CHAINID,
20.241 + g_param_spec_string ("mythtv-live-chainid", "mythtv-live-chainid",
20.242 + "Sets the MythTV chain ID (from TV Chain)", "", G_PARAM_READWRITE));
20.243 +
20.244 + g_object_class_install_property
20.245 + (gobject_class, PROP_GMYTHTV_LIVE,
20.246 + g_param_spec_boolean ("mythtv-live", "mythtv-live",
20.247 + "Enable MythTV Live TV content streaming", FALSE, G_PARAM_READWRITE));
20.248 +
20.249 + g_object_class_install_property
20.250 + (gobject_class, PROP_GMYTHTV_ENABLE_TIMING_POSITION,
20.251 + g_param_spec_boolean ("mythtv-enable-timing-position",
20.252 + "mythtv-enable-timing-position",
20.253 + "Enable MythTV Live TV content size continuous updating", FALSE,
20.254 + G_PARAM_READWRITE));
20.255 +
20.256 + g_object_class_install_property
20.257 + (gobject_class, PROP_GMYTHTV_CHANNEL_NUM,
20.258 + g_param_spec_string ("mythtv-channel", "mythtv-channel",
20.259 + "Change MythTV channel number",
20.260 + "", G_PARAM_READWRITE));
20.261 +
20.262 + g_object_class_install_property
20.263 + (gobject_class, PROP_GMYTHTV_MAX_TRY,
20.264 + g_param_spec_int ("max-try", "max-try",
20.265 + "Set the max try for get MythTV free recorder",
20.266 + 0, G_MAXINT, 10, G_PARAM_READWRITE));
20.267 +
20.268 +
20.269 +#ifndef GST_DISABLE_GST_DEBUG
20.270 + g_object_class_install_property
20.271 + (gobject_class, PROP_GMYTHTV_DBG,
20.272 + g_param_spec_boolean ("mythtv-debug", "mythtv-debug",
20.273 + "Enable MythTV debug messages", FALSE, G_PARAM_READWRITE));
20.274 +#endif
20.275 +
20.276 + gstbasesrc_class->start = gst_mythtv_src_start;
20.277 + gstbasesrc_class->stop = gst_mythtv_src_stop;
20.278 + gstbasesrc_class->get_size = gst_mythtv_src_get_size;
20.279 + gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
20.280 +
20.281 + gstbasesrc_class->do_seek = gst_mythtv_src_do_seek;
20.282 + gstpushsrc_class->create = gst_mythtv_src_create;
20.283 +
20.284 + GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
20.285 + "MythTV Client Source");
20.286 +}
20.287 +
20.288 +static void
20.289 +gst_mythtv_src_init (GstMythtvSrc * this, GstMythtvSrcClass * g_class)
20.290 +{
20.291 + this->file = NULL;
20.292 +
20.293 + this->unique_setup = FALSE;
20.294 +
20.295 + this->mythtv_version = GMYTHTV_VERSION_DEFAULT;
20.296 +
20.297 + this->state = GST_MYTHTV_SRC_FILE_TRANSFER;
20.298 +
20.299 + this->bytes_read = 0;
20.300 +
20.301 + this->prev_content_size = 0;
20.302 +
20.303 + this->content_size = 0;
20.304 + this->read_offset = 0;
20.305 +
20.306 + this->content_size_last = 0;
20.307 +
20.308 + this->live_tv = FALSE;
20.309 +
20.310 + this->enable_timing_position = FALSE;
20.311 + this->update_prog_chain = FALSE;
20.312 +
20.313 + this->user_agent = g_strdup ("mythtvsrc");
20.314 + this->update_prog_chain = FALSE;
20.315 +
20.316 + this->channel_name = NULL;
20.317 +
20.318 + this->eos = FALSE;
20.319 +
20.320 + this->bytes_queue = NULL;
20.321 +
20.322 + this->wait_to_transfer = 0;
20.323 + this->try_number = 0;
20.324 + this->max_try = 10;
20.325 +
20.326 + gst_base_src_set_format (GST_BASE_SRC (this), GST_FORMAT_BYTES);
20.327 +
20.328 + gst_pad_set_event_function (GST_BASE_SRC_PAD (GST_BASE_SRC (this)),
20.329 + gst_mythtv_src_handle_event);
20.330 + gst_pad_set_query_function (GST_BASE_SRC_PAD (GST_BASE_SRC (this)),
20.331 + gst_mythtv_src_handle_query);
20.332 +
20.333 +}
20.334 +
20.335 +static void
20.336 +gst_mythtv_src_clear (GstMythtvSrc *mythtv_src)
20.337 +{
20.338 + mythtv_src->unique_setup = FALSE;
20.339 + mythtv_src->try_number = 0;
20.340 +
20.341 + if (mythtv_src->spawn_livetv) {
20.342 + g_object_unref (mythtv_src->spawn_livetv);
20.343 + mythtv_src->spawn_livetv = NULL;
20.344 + }
20.345 +
20.346 + if (mythtv_src->file) {
20.347 + g_object_unref (mythtv_src->file);
20.348 + mythtv_src->file = NULL;
20.349 + }
20.350 +
20.351 + if (mythtv_src->backend_info) {
20.352 + g_object_unref (mythtv_src->backend_info);
20.353 + mythtv_src->backend_info = NULL;
20.354 + }
20.355 +
20.356 + if (mythtv_src->bytes_queue) {
20.357 + g_byte_array_free (mythtv_src->bytes_queue, TRUE);
20.358 + mythtv_src->bytes_queue = NULL;
20.359 + }
20.360 +
20.361 +}
20.362 +
20.363 +static void
20.364 +gst_mythtv_src_finalize (GObject * gobject)
20.365 +{
20.366 + GstMythtvSrc *this = GST_MYTHTV_SRC (gobject);
20.367 +
20.368 + gst_mythtv_src_clear (this);
20.369 +
20.370 + if (this->uri_name) {
20.371 + g_free (this->uri_name);
20.372 + this->uri_name = NULL;
20.373 + }
20.374 +
20.375 + if (this->user_agent) {
20.376 + g_free (this->user_agent);
20.377 + this->user_agent = NULL;
20.378 + }
20.379 +
20.380 + G_OBJECT_CLASS (parent_class)->finalize (gobject);
20.381 +}
20.382 +
20.383 +static GMythFileReadResult
20.384 +do_read_request_response (GstMythtvSrc * src, guint size, GByteArray *data_ptr)
20.385 +{
20.386 + gint read = 0;
20.387 + guint sizetoread = size;
20.388 + gint max_iters = GMYTHTV_TRANSFER_MAX_RESENDS;
20.389 + GMythFileReadResult result;
20.390 +
20.391 + GST_LOG_OBJECT (src, "Starting: Reading %d bytes...", sizetoread);
20.392 +
20.393 + /* Loop sending the Myth File Transfer request:
20.394 + * Retry whilst authentication fails and we supply it. */
20.395 +
20.396 + while (sizetoread == size && --max_iters > 0) {
20.397 + /* if ( gmyth_backend_info_is_local_file(src->backend_info) ) */
20.398 + if ( IS_GMYTH_FILE_LOCAL(src->file) )
20.399 + result = gmyth_file_local_read ( GMYTH_FILE_LOCAL(src->file),
20.400 + data_ptr, sizetoread, src->live_tv);
20.401 + else if ( IS_GMYTH_FILE_TRANSFER(src->file) )
20.402 + result = gmyth_file_transfer_read ( GMYTH_FILE_TRANSFER(src->file),
20.403 + data_ptr, sizetoread, src->live_tv);
20.404 +
20.405 + if (data_ptr->len > 0) {
20.406 + read += data_ptr->len;
20.407 + sizetoread -= data_ptr->len;
20.408 + } else if (data_ptr->len < 0) {
20.409 + if (src->live_tv == FALSE) {
20.410 + result = GMYTH_FILE_READ_EOF;
20.411 + goto eos;
20.412 + } else {
20.413 + if (result == GMYTH_FILE_READ_ERROR) { /* -314 */
20.414 + GST_INFO_OBJECT (src, "[LiveTV] FileTransfer READ_ERROR!");
20.415 + goto done;
20.416 + } else if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) { /* -315 */
20.417 + GST_INFO_OBJECT (src,
20.418 + "[LiveTV] FileTransfer - Go to the next program chain!");
20.419 + continue;
20.420 + }
20.421 + goto done;
20.422 + }
20.423 +
20.424 + } else if (data_ptr->len == 0)
20.425 + goto done;
20.426 +
20.427 + if (read == sizetoread)
20.428 + goto done;
20.429 + }
20.430 +
20.431 + if ((read < 0 && !src->live_tv) || max_iters == 0){
20.432 + result = GMYTH_FILE_READ_EOF;
20.433 + goto eos;
20.434 + }
20.435 +
20.436 + goto done;
20.437 +
20.438 +eos:
20.439 + src->eos = TRUE;
20.440 +
20.441 +done:
20.442 + return result;
20.443 +}
20.444 +
20.445 +static GstFlowReturn
20.446 +gst_mythtv_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
20.447 +{
20.448 + GstMythtvSrc *src;
20.449 + GstFlowReturn ret = GST_FLOW_OK;
20.450 + guint buffer_size_inter = 0;
20.451 +
20.452 + src = GST_MYTHTV_SRC (psrc);
20.453 +
20.454 + /* The caller should know the number of bytes and not read beyond EOS. */
20.455 + if (G_UNLIKELY (src->eos))
20.456 + goto eos;
20.457 + if (G_UNLIKELY (src->update_prog_chain))
20.458 + goto change_progchain;
20.459 +
20.460 + GST_DEBUG_OBJECT (src, "offset = %" G_GUINT64_FORMAT ", size = %d...",
20.461 + src->read_offset, MAX_READ_SIZE);
20.462 +
20.463 + GST_DEBUG_OBJECT (src, "Create: buffer_remain: %d, buffer_size = %d.",
20.464 + (gint) src->buffer_remain, src->bytes_queue->len);
20.465 +
20.466 +program_chain_changed:
20.467 + /* just get from the byte array, no network effort... */
20.468 + if ((src->buffer_remain = src->bytes_queue->len) < MAX_READ_SIZE) {
20.469 + GByteArray *buffer;
20.470 + GMythFileReadResult result = GMYTH_FILE_READ_OK;
20.471 +
20.472 + buffer = NULL;
20.473 + buffer_size_inter = (INTERNAL_BUFFER_SIZE - src->buffer_remain);
20.474 +
20.475 + if (buffer_size_inter > REQUEST_MAX_SIZE)
20.476 + buffer_size_inter = REQUEST_MAX_SIZE;
20.477 +
20.478 + buffer = g_byte_array_new ();
20.479 +
20.480 + result = do_read_request_response (src, buffer_size_inter, buffer);
20.481 +
20.482 + if (G_UNLIKELY (buffer->len < 0)) {
20.483 +
20.484 + if (buffer != NULL) {
20.485 + g_byte_array_free (buffer, TRUE);
20.486 + buffer = NULL;
20.487 + }
20.488 +
20.489 + if (src->live_tv || ( result == GMYTH_FILE_READ_NEXT_PROG_CHAIN ))
20.490 + goto change_progchain;
20.491 + else
20.492 + goto read_error;
20.493 + } else if (G_UNLIKELY (read == 0)) {
20.494 +
20.495 + if (buffer != NULL) {
20.496 + g_byte_array_free (buffer, TRUE);
20.497 + buffer = NULL;
20.498 + }
20.499 +
20.500 + if (!src->live_tv)
20.501 + goto done;
20.502 + else
20.503 + goto program_chain_changed;
20.504 + }
20.505 +
20.506 + if (G_UNLIKELY (src->update_prog_chain))
20.507 + {
20.508 + if (buffer != NULL) {
20.509 + g_byte_array_free (buffer, TRUE);
20.510 + buffer = NULL;
20.511 + }
20.512 + goto change_progchain;
20.513 + }
20.514 +
20.515 + src->bytes_queue =
20.516 + g_byte_array_append (src->bytes_queue, buffer->data, buffer->len);
20.517 + if (buffer->len > buffer_size_inter)
20.518 + GST_WARNING_OBJECT (src,
20.519 + "INCREASED buffer size! Backend sent more than we ask him... (%d)",
20.520 + abs (buffer->len - buffer_size_inter));
20.521 +
20.522 + src->buffer_remain += buffer->len;
20.523 +
20.524 + if (buffer != NULL) {
20.525 + g_byte_array_free (buffer, TRUE);
20.526 + buffer = NULL;
20.527 + }
20.528 +
20.529 + GST_DEBUG_OBJECT (src,
20.530 + "BYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "
20.531 + "OFFSET = %llu, CONTENT SIZE = %llu.", read,
20.532 + src->bytes_read, src->read_offset, src->content_size);
20.533 +
20.534 + }
20.535 +
20.536 + guint buffer_size =
20.537 + (src->buffer_remain < MAX_READ_SIZE) ? src->buffer_remain : MAX_READ_SIZE;
20.538 +
20.539 + *outbuf = gst_buffer_new ();
20.540 +
20.541 + /* gets the first buffer_size bytes from the byte array buffer variable */
20.542 + /* guint8 *buf = g_memdup( src->bytes_queue->data, buffer_size ); */
20.543 +
20.544 + GST_DEBUG_OBJECT (src, "read from network? %s!, buffer_remain = %d",
20.545 + (buffer_size_inter ==
20.546 + 0) ? "NO, got from buffer" : "YES, go see the backend's log file",
20.547 + src->buffer_remain);
20.548 +
20.549 + GST_BUFFER_SIZE (*outbuf) = buffer_size;
20.550 + GST_BUFFER_MALLOCDATA (*outbuf) = g_malloc0 (GST_BUFFER_SIZE (*outbuf));
20.551 + GST_BUFFER_DATA (*outbuf) = GST_BUFFER_MALLOCDATA (*outbuf);
20.552 + g_memmove (GST_BUFFER_DATA ((*outbuf)), src->bytes_queue->data,
20.553 + GST_BUFFER_SIZE (*outbuf));
20.554 + GST_BUFFER_OFFSET (*outbuf) = src->read_offset;
20.555 + GST_BUFFER_OFFSET_END (*outbuf) =
20.556 + src->read_offset + GST_BUFFER_SIZE (*outbuf);
20.557 +
20.558 + src->buffer_remain -= GST_BUFFER_SIZE (*outbuf);
20.559 +
20.560 + src->read_offset += GST_BUFFER_SIZE (*outbuf);
20.561 + src->bytes_read += GST_BUFFER_SIZE (*outbuf);
20.562 + GST_DEBUG_OBJECT (src, "Buffer output with size: %d",
20.563 + GST_BUFFER_SIZE (*outbuf));
20.564 +
20.565 + /* flushs the newly buffer got from byte array */
20.566 + src->bytes_queue =
20.567 + g_byte_array_remove_range (src->bytes_queue, 0, buffer_size);
20.568 +
20.569 + GST_DEBUG_OBJECT ( src, "Got buffer: BUFFER --->SIZE = %d, OFFSET = %llu, "
20.570 + "OFFSET_END = %llu.", GST_BUFFER_SIZE (*outbuf),
20.571 + GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf) );
20.572 +
20.573 + GST_DEBUG_OBJECT (src, "CONTENT_SIZE = %llu, BYTES_READ = %llu.",
20.574 + src->content_size, src->bytes_read);
20.575 +
20.576 + if ( G_UNLIKELY (src->eos) || ( !src->live_tv
20.577 + && ( src->bytes_read >= src->content_size ) ) )
20.578 + goto eos;
20.579 +
20.580 +done:
20.581 + {
20.582 + const gchar *reason = gst_flow_get_name (ret);
20.583 +
20.584 + GST_DEBUG_OBJECT (src, "DONE task, reason %s", reason);
20.585 + return ret;
20.586 + }
20.587 +eos:
20.588 + {
20.589 + const gchar *reason = gst_flow_get_name (ret);
20.590 +
20.591 + GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
20.592 + return GST_FLOW_UNEXPECTED;
20.593 + }
20.594 + /* ERRORS */
20.595 +read_error:
20.596 + {
20.597 + GST_ELEMENT_ERROR (src, RESOURCE, READ,
20.598 + (NULL), ("Could not read any bytes (%i, %s)", read, src->uri_name));
20.599 + return GST_FLOW_ERROR;
20.600 + }
20.601 +change_progchain:
20.602 + {
20.603 + GST_ELEMENT_ERROR (src, RESOURCE, READ,
20.604 + (NULL), ("Seek failed, go to the next program info... (%i, %s)", read,
20.605 + src->uri_name));
20.606 +
20.607 +/*
20.608 + TODO: need to send a new segment event to NUVDemux?
20.609 + gst_pad_push_event (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
20.610 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0, -1, 0));
20.611 +*/
20.612 +
20.613 + goto program_chain_changed;
20.614 + }
20.615 +
20.616 +}
20.617 +
20.618 +gint64
20.619 +gst_mythtv_src_get_position (GstMythtvSrc * src)
20.620 +{
20.621 +
20.622 + gint64 size_tmp = 0;
20.623 + guint max_tries = 2;
20.624 +
20.625 + if (src->live_tv == TRUE && (abs (src->content_size - src->bytes_read) <
20.626 + GMYTHTV_TRANSFER_MAX_BUFFER)) {
20.627 +
20.628 + get_file_pos:
20.629 + g_usleep (10);
20.630 + size_tmp = gmyth_recorder_get_file_position (src->spawn_livetv->recorder);
20.631 + if (size_tmp > (src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER))
20.632 + src->content_size = size_tmp;
20.633 + else if (size_tmp > 0 && --max_tries > 0)
20.634 + goto get_file_pos;
20.635 + GST_LOG_OBJECT (src, "GET_POSITION: file_position = %lld", size_tmp);
20.636 + /* sets the last content size amount before it can be updated */
20.637 + src->prev_content_size = src->content_size;
20.638 + }
20.639 +
20.640 + return src->content_size;
20.641 +
20.642 +}
20.643 +
20.644 +static gboolean
20.645 +gst_mythtv_src_do_seek (GstBaseSrc * base, GstSegment * segment)
20.646 +{
20.647 + GstMythtvSrc *src = GST_MYTHTV_SRC (base);
20.648 + gint64 new_offset = -1;
20.649 + gint64 actual_seek = segment->start;
20.650 + gboolean ret = TRUE;
20.651 +
20.652 + GST_LOG_OBJECT (src, "seek, segment: %" GST_SEGMENT_FORMAT, segment);
20.653 +
20.654 + if (segment->format == GST_FORMAT_TIME) {
20.655 + goto done;
20.656 + }
20.657 + GST_LOG_OBJECT (src,
20.658 + "Trying to seek at the value (actual_seek = %lld, read_offset = %lld)",
20.659 + actual_seek, src->read_offset);
20.660 + /* verify if it needs to seek */
20.661 + if (src->read_offset != actual_seek) {
20.662 +
20.663 + /* if ( gmyth_backend_info_is_local_file(src->backend_info) ) */
20.664 + if ( IS_GMYTH_FILE_LOCAL(src->file) )
20.665 + new_offset =
20.666 + gmyth_file_local_seek ( GMYTH_FILE_LOCAL(src->file), segment->start, G_SEEK_SET);
20.667 + else if ( IS_GMYTH_FILE_TRANSFER(src->file) )
20.668 + new_offset =
20.669 + gmyth_file_transfer_seek ( GMYTH_FILE_TRANSFER(src->file), segment->start, SEEK_SET);
20.670 +
20.671 + GST_LOG_OBJECT (src,
20.672 + "Segment offset start = %lld, SRC Offset = %lld, NEW actual backend SEEK Offset = %lld.",
20.673 + segment->start, src->read_offset, new_offset);
20.674 + if (G_UNLIKELY (new_offset < 0)) {
20.675 + ret = FALSE;
20.676 + if (!src->live_tv)
20.677 + goto eos;
20.678 + }
20.679 +
20.680 + src->read_offset = new_offset;
20.681 +
20.682 + if (ret == FALSE) {
20.683 + GST_INFO_OBJECT (src, "Failed to set the SEEK on segment!");
20.684 + }
20.685 +
20.686 + }
20.687 +
20.688 +done:
20.689 + return ret;
20.690 +
20.691 +eos:
20.692 + {
20.693 + GST_DEBUG_OBJECT (src, "EOS found on seeking!!!");
20.694 + return FALSE;
20.695 + }
20.696 +
20.697 +}
20.698 +
20.699 +/* create a socket for connecting to remote server */
20.700 +static gboolean
20.701 +gst_mythtv_src_start (GstBaseSrc * bsrc)
20.702 +{
20.703 + GstMythtvSrc *src = GST_MYTHTV_SRC (bsrc);
20.704 +
20.705 + GString *chain_id_local = NULL;
20.706 + GMythURI *gmyth_uri = NULL;
20.707 + gboolean ret = TRUE;
20.708 +
20.709 + if (src->unique_setup == FALSE) {
20.710 + src->unique_setup = TRUE;
20.711 + } else {
20.712 + goto done;
20.713 + }
20.714 +
20.715 + gmyth_uri = gmyth_uri_new_with_value (src->uri_name);
20.716 + src->backend_info = gmyth_backend_info_new_with_uri (src->uri_name);
20.717 + src->live_tv = gmyth_uri_is_livetv( gmyth_uri );
20.718 + /* testing UPnP... */
20.719 + /* gmyth_backend_info_set_hostname( src->backend_info, NULL ); */
20.720 + if ( src->live_tv ) {
20.721 + src->spawn_livetv = gmyth_livetv_new (src->backend_info);
20.722 +
20.723 + gchar* ch = gmyth_uri_get_channel_name( gmyth_uri );
20.724 + if ( ch != NULL )
20.725 + src->channel_name = ch;
20.726 +
20.727 + if (src->channel_name != NULL) {
20.728 + if (gmyth_livetv_channel_name_setup (src->spawn_livetv, src->channel_name) == FALSE) {
20.729 + GST_INFO_OBJECT (src, "LiveTV setup felt down on error");
20.730 + ret = FALSE;
20.731 + goto init_failed;
20.732 + }
20.733 + } else {
20.734 + if (gmyth_livetv_setup (src->spawn_livetv) == FALSE) {
20.735 + GST_INFO_OBJECT (src, "LiveTV setup felt down on error");
20.736 + ret = FALSE;
20.737 + goto init_failed;
20.738 + }
20.739 + }
20.740 +
20.741 + /* testing change channel... */
20.742 + /* gmyth_recorder_change_channel( src->spawn_livetv->recorder, CHANNEL_DIRECTION_UP ); */
20.743 +
20.744 + src->file = GMYTH_FILE( gmyth_livetv_create_file_transfer (src->spawn_livetv) );
20.745 +
20.746 + if (NULL == src->file) {
20.747 + GST_INFO_OBJECT (src, "[LiveTV] FileTransfer equals to NULL");
20.748 + ret = FALSE;
20.749 + goto init_failed;
20.750 + }
20.751 +
20.752 + /* Check if the file is local to this specific client renderer */
20.753 + if ( gmyth_uri_is_local_file(gmyth_uri) )
20.754 + ret = gmyth_file_local_open( GMYTH_FILE_LOCAL(src->file) );
20.755 + else
20.756 + ret = gmyth_file_transfer_open( GMYTH_FILE_TRANSFER(src->file), src->spawn_livetv->uri != NULL ?
20.757 + gmyth_uri_get_path(src->spawn_livetv->uri) :
20.758 + src->spawn_livetv->proginfo->pathname->str );
20.759 +
20.760 + /* sets the mythtvsrc "location" property */
20.761 + g_object_set (src, "location", gmyth_file_get_uri (src->file), NULL);
20.762 +
20.763 + if ( !ret )
20.764 + {
20.765 + GST_INFO_OBJECT (src, "Error: couldn't open the FileTransfer from LiveTV source!" );
20.766 + g_object_unref( src->file );
20.767 + src->file = NULL;
20.768 + goto init_failed;
20.769 + }
20.770 + } else {
20.771 +
20.772 + /* Check if the file is local to this specific client renderer, and tries to open
20.773 + * a local connection
20.774 + */
20.775 + if ( gmyth_uri_is_local_file(gmyth_uri) )
20.776 + {
20.777 + src->file = GMYTH_FILE(gmyth_file_local_new(src->backend_info));
20.778 + ret = gmyth_file_local_open ( GMYTH_FILE_LOCAL( src->file ) );
20.779 + } else {
20.780 + src->file = GMYTH_FILE(gmyth_file_transfer_new(src->backend_info));
20.781 + ret = gmyth_file_transfer_open ( GMYTH_FILE_TRANSFER(src->file), src->uri_name );
20.782 + }
20.783 +
20.784 + } /* if (else) - recorded FileTransfer */
20.785 +
20.786 + if (NULL == src->file) {
20.787 + GST_INFO_OBJECT (src, "FileTransfer is NULL");
20.788 + goto init_failed;
20.789 + }
20.790 + /*GST_INFO_OBJECT( src, "uri = %s", src->spawn_livetv->file); */
20.791 +
20.792 + if (ret == FALSE) {
20.793 +#ifndef GST_DISABLE_GST_DEBUG
20.794 + if (src->mythtv_msgs_dbg)
20.795 + GST_INFO_OBJECT (src,
20.796 + "MythTV FileTransfer request failed when setting up socket connection!");
20.797 +#endif
20.798 + goto begin_req_failed;
20.799 + }
20.800 +
20.801 + GST_INFO_OBJECT (src,
20.802 + "MythTV FileTransfer filesize = %lld, content_size = %lld!",
20.803 + gmyth_file_get_filesize( src->file ), src->content_size);
20.804 +
20.805 + src->content_size = gmyth_file_get_filesize (src->file);
20.806 +
20.807 + src->do_start = FALSE;
20.808 +
20.809 + /* this is used for the buffer cache */
20.810 + src->bytes_queue = g_byte_array_sized_new (INTERNAL_BUFFER_SIZE);
20.811 + src->buffer_remain = 0;
20.812 +
20.813 + gst_pad_push_event (GST_BASE_SRC_PAD (GST_BASE_SRC (src)),
20.814 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0,
20.815 + src->content_size, 0));
20.816 +
20.817 +done:
20.818 + if (gmyth_uri != NULL)
20.819 + {
20.820 + g_object_unref (gmyth_uri);
20.821 + gmyth_uri = NULL;
20.822 + }
20.823 +
20.824 + if (chain_id_local != NULL) {
20.825 + g_string_free (chain_id_local, TRUE);
20.826 + chain_id_local = NULL;
20.827 + }
20.828 +
20.829 + return TRUE;
20.830 +
20.831 + /* ERRORS */
20.832 +init_failed:
20.833 + if (gmyth_uri != NULL)
20.834 + {
20.835 + g_object_unref (gmyth_uri);
20.836 + gmyth_uri = NULL;
20.837 + }
20.838 +
20.839 + if (src->spawn_livetv != NULL) {
20.840 + g_object_unref (src->spawn_livetv);
20.841 + src->spawn_livetv = NULL;
20.842 + }
20.843 +
20.844 + /*
20.845 + GST_ELEMENT_ERROR (src, LIBRARY, INIT,
20.846 + (NULL), ("Could not initialize MythTV library (%i, %s)", ret,
20.847 + src->uri_name));
20.848 + */
20.849 +
20.850 + if (++src->try_number <= src->max_try) {
20.851 + gst_mythtv_src_clear (src);
20.852 + GST_DEBUG_OBJECT (src, "Starting new try for get free recorder on MythTV");
20.853 + g_usleep (0.5 * G_USEC_PER_SEC);
20.854 + return gst_mythtv_src_start (bsrc);
20.855 + }
20.856 +
20.857 + return FALSE;
20.858 +begin_req_failed:
20.859 + if (gmyth_uri != NULL)
20.860 + {
20.861 + g_object_unref (gmyth_uri);
20.862 + gmyth_uri = NULL;
20.863 + }
20.864 +
20.865 + GST_ELEMENT_ERROR (src, LIBRARY, INIT,
20.866 + (NULL), ("Could not begin request sent to MythTV server (%i, %s)", ret,
20.867 + src->uri_name));
20.868 + return FALSE;
20.869 +
20.870 +}
20.871 +
20.872 +static gboolean
20.873 +gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size)
20.874 +{
20.875 + GstMythtvSrc *src = GST_MYTHTV_SRC (bsrc);
20.876 + gboolean ret = TRUE;
20.877 +
20.878 + GST_LOG_OBJECT (src, "Differs from previous content size: %d (max.: %d)",
20.879 + abs (src->content_size - src->prev_content_size),
20.880 + GMYTHTV_TRANSFER_MAX_BUFFER);
20.881 +
20.882 + if (src->live_tv) {
20.883 + ret = FALSE;
20.884 + } else if (src->live_tv && src->enable_timing_position
20.885 + && (abs (src->content_size - src->bytes_read) <
20.886 + GMYTHTV_TRANSFER_MAX_BUFFER)) {
20.887 +
20.888 + gint64 new_offset =
20.889 + gmyth_recorder_get_file_position (src->spawn_livetv->recorder);
20.890 + if (new_offset > 0 && new_offset > src->content_size) {
20.891 + src->content_size = new_offset;
20.892 + } else if (new_offset < src->content_size) {
20.893 + src->update_prog_chain = TRUE;
20.894 + }
20.895 +
20.896 + }
20.897 +
20.898 + *size = src->content_size;
20.899 + GST_LOG_OBJECT (src, "Content size = %lld", src->content_size);
20.900 +
20.901 + return ret;
20.902 +
20.903 +}
20.904 +
20.905 +/* close the socket and associated resources
20.906 + * used both to recover from errors and go to NULL state */
20.907 +static gboolean
20.908 +gst_mythtv_src_stop (GstBaseSrc * bsrc)
20.909 +{
20.910 + GstMythtvSrc *src = GST_MYTHTV_SRC (bsrc);
20.911 +
20.912 + gst_mythtv_src_clear (src);
20.913 +
20.914 + /* src->eos = FALSE; */
20.915 +
20.916 + return TRUE;
20.917 +}
20.918 +
20.919 +static gboolean
20.920 +gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event)
20.921 +{
20.922 + GstMythtvSrc *src = GST_MYTHTV_SRC (GST_PAD_PARENT (pad));
20.923 + gint64 cont_size = 0;
20.924 + gboolean ret = FALSE;
20.925 +
20.926 + switch (GST_EVENT_TYPE (event)) {
20.927 + case GST_EVENT_EOS:
20.928 + GST_WARNING_OBJECT (src, "Got EOS event");
20.929 +
20.930 + if (src->live_tv) {
20.931 + cont_size = gst_mythtv_src_get_position (src);
20.932 + if (cont_size > src->content_size) {
20.933 + src->content_size = cont_size;
20.934 + src->eos = FALSE;
20.935 + } else {
20.936 + src->eos = TRUE;
20.937 + gst_element_set_state (GST_ELEMENT (src), GST_STATE_NULL);
20.938 + gst_element_set_locked_state (GST_ELEMENT (src), FALSE);
20.939 + }
20.940 + }
20.941 + break;
20.942 + default:
20.943 + ret = gst_pad_event_default (pad, event);
20.944 + }
20.945 +
20.946 + return ret;
20.947 +}
20.948 +
20.949 +static gboolean
20.950 +gst_mythtv_src_is_seekable (GstBaseSrc * push_src)
20.951 +{
20.952 + return TRUE;
20.953 +}
20.954 +
20.955 +static gboolean
20.956 +gst_mythtv_src_handle_query (GstPad * pad, GstQuery * query)
20.957 +{
20.958 + gboolean res = FALSE;
20.959 + GstMythtvSrc *myth = GST_MYTHTV_SRC (gst_pad_get_parent (pad));
20.960 + GstFormat formt;
20.961 +
20.962 + switch (GST_QUERY_TYPE (query)) {
20.963 + case GST_QUERY_POSITION:
20.964 + {
20.965 + gst_query_parse_position (query, &formt, NULL);
20.966 + if (formt == GST_FORMAT_BYTES) {
20.967 + gst_query_set_position (query, formt, myth->read_offset);
20.968 + GST_DEBUG_OBJECT (myth, "POS %" G_GINT64_FORMAT, myth->read_offset);
20.969 + res = TRUE;
20.970 + } else if (formt == GST_FORMAT_TIME) {
20.971 + res = gst_pad_query_default (pad, query);
20.972 + }
20.973 + break;
20.974 + }
20.975 + case GST_QUERY_DURATION:
20.976 + {
20.977 +#if 0
20.978 + if (myth->duration != 0) {
20.979 + gint64 total;
20.980 + gint64 fps;
20.981 +
20.982 + fps = nuv->h->i_fpsn / nuv->h->i_fpsd;
20.983 + total =
20.984 + gst_util_uint64_scale_int (GST_SECOND, nuv->h->i_video_blocks, fps);
20.985 + }
20.986 +#endif
20.987 +
20.988 + gst_query_parse_duration (query, &formt, NULL);
20.989 + if (formt == GST_FORMAT_BYTES) {
20.990 + gst_query_set_duration (query, formt, myth->content_size);
20.991 + GST_DEBUG_OBJECT (myth, "SIZE %" G_GINT64_FORMAT, myth->content_size);
20.992 + res = TRUE;
20.993 + } else if (formt == GST_FORMAT_TIME) {
20.994 + res = gst_pad_query_default (pad, query);
20.995 + }
20.996 + break;
20.997 + }
20.998 + default:
20.999 + {
20.1000 + res = gst_pad_query_default (pad, query);
20.1001 + break;
20.1002 + }
20.1003 + }
20.1004 +
20.1005 + gst_object_unref (myth);
20.1006 +
20.1007 + return res;
20.1008 +}
20.1009 +
20.1010 +static GstStateChangeReturn
20.1011 +gst_mythtv_src_change_state (GstElement * element, GstStateChange transition)
20.1012 +{
20.1013 + GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
20.1014 + GstMythtvSrc *src = GST_MYTHTV_SRC (element);
20.1015 +
20.1016 + switch (transition) {
20.1017 + case GST_STATE_CHANGE_NULL_TO_READY:
20.1018 + break;
20.1019 + case GST_STATE_CHANGE_READY_TO_PAUSED:
20.1020 + case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
20.1021 + if (src->live_tv) {
20.1022 + if (!gmyth_recorder_send_frontend_ready_command (src->spawn_livetv->
20.1023 + recorder))
20.1024 + GST_WARNING_OBJECT (src,
20.1025 + "Couldn't send the FRONTEND_READY message to the backend!");
20.1026 + else
20.1027 + GST_DEBUG_OBJECT (src, "FRONTEND_READY was sent to the backend");
20.1028 + }
20.1029 + break;
20.1030 + default:
20.1031 + break;
20.1032 + }
20.1033 +
20.1034 + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
20.1035 + if (ret == GST_STATE_CHANGE_FAILURE)
20.1036 + return ret;
20.1037 +
20.1038 + switch (transition) {
20.1039 + case GST_STATE_CHANGE_READY_TO_NULL:
20.1040 + break;
20.1041 + case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
20.1042 + case GST_STATE_CHANGE_PAUSED_TO_READY:
20.1043 + break;
20.1044 + default:
20.1045 + break;
20.1046 + }
20.1047 +
20.1048 + return ret;
20.1049 +}
20.1050 +
20.1051 +static void
20.1052 +gst_mythtv_src_set_property (GObject * object, guint prop_id,
20.1053 + const GValue * value, GParamSpec * pspec)
20.1054 +{
20.1055 + GstMythtvSrc *mythtvsrc = GST_MYTHTV_SRC (object);
20.1056 +
20.1057 + GST_OBJECT_LOCK (mythtvsrc);
20.1058 + switch (prop_id) {
20.1059 + case PROP_LOCATION:
20.1060 + {
20.1061 + if (!g_value_get_string (value)) {
20.1062 + GST_WARNING ("location property cannot be NULL");
20.1063 + break;
20.1064 + }
20.1065 +
20.1066 + if (mythtvsrc->uri_name != NULL) {
20.1067 + g_free (mythtvsrc->uri_name);
20.1068 + mythtvsrc->uri_name = NULL;
20.1069 + }
20.1070 + mythtvsrc->uri_name = g_value_dup_string (value);
20.1071 +
20.1072 + break;
20.1073 + }
20.1074 +#ifndef GST_DISABLE_GST_DEBUG
20.1075 + case PROP_GMYTHTV_DBG:
20.1076 + {
20.1077 + mythtvsrc->mythtv_msgs_dbg = g_value_get_boolean (value);
20.1078 + break;
20.1079 + }
20.1080 +#endif
20.1081 + case PROP_GMYTHTV_VERSION:
20.1082 + {
20.1083 + mythtvsrc->mythtv_version = g_value_get_int (value);
20.1084 + break;
20.1085 + }
20.1086 + case PROP_GMYTHTV_LIVEID:
20.1087 + {
20.1088 + mythtvsrc->live_tv_id = g_value_get_int (value);
20.1089 + break;
20.1090 + }
20.1091 + case PROP_GMYTHTV_LIVE:
20.1092 + {
20.1093 + mythtvsrc->live_tv = g_value_get_boolean (value);
20.1094 + break;
20.1095 + }
20.1096 + case PROP_GMYTHTV_ENABLE_TIMING_POSITION:
20.1097 + {
20.1098 + mythtvsrc->enable_timing_position = g_value_get_boolean (value);
20.1099 + break;
20.1100 + }
20.1101 + case PROP_GMYTHTV_LIVE_CHAINID:
20.1102 + {
20.1103 + if (!g_value_get_string (value)) {
20.1104 + GST_WARNING ("MythTV Live chainid property cannot be NULL");
20.1105 + break;
20.1106 + }
20.1107 +
20.1108 + if (mythtvsrc->live_chain_id != NULL) {
20.1109 + g_free (mythtvsrc->live_chain_id);
20.1110 + mythtvsrc->live_chain_id = NULL;
20.1111 + }
20.1112 + mythtvsrc->live_chain_id = g_value_dup_string (value);
20.1113 + break;
20.1114 + }
20.1115 + case PROP_GMYTHTV_CHANNEL_NUM:
20.1116 + {
20.1117 + mythtvsrc->channel_name = g_value_dup_string (value);
20.1118 + break;
20.1119 + }
20.1120 + case PROP_GMYTHTV_MAX_TRY:
20.1121 + {
20.1122 + mythtvsrc->max_try = g_value_get_int (value);
20.1123 + break;
20.1124 + }
20.1125 + default:
20.1126 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
20.1127 + break;
20.1128 + }
20.1129 +
20.1130 + GST_OBJECT_UNLOCK (mythtvsrc);
20.1131 +}
20.1132 +
20.1133 +static void
20.1134 +gst_mythtv_src_get_property (GObject * object, guint prop_id,
20.1135 + GValue * value, GParamSpec * pspec)
20.1136 +{
20.1137 + GstMythtvSrc *mythtvsrc = GST_MYTHTV_SRC (object);
20.1138 +
20.1139 + GST_OBJECT_LOCK (mythtvsrc);
20.1140 + switch (prop_id) {
20.1141 + case PROP_LOCATION:
20.1142 + {
20.1143 + g_value_set_string (value, mythtvsrc->uri_name);
20.1144 + break;
20.1145 + }
20.1146 +#ifndef GST_DISABLE_GST_DEBUG
20.1147 + case PROP_GMYTHTV_DBG:
20.1148 + g_value_set_boolean (value, mythtvsrc->mythtv_msgs_dbg);
20.1149 + break;
20.1150 +#endif
20.1151 + case PROP_GMYTHTV_VERSION:
20.1152 + {
20.1153 + g_value_set_int (value, mythtvsrc->mythtv_version);
20.1154 + break;
20.1155 + }
20.1156 + case PROP_GMYTHTV_LIVEID:
20.1157 + {
20.1158 + g_value_set_int (value, mythtvsrc->live_tv_id);
20.1159 + break;
20.1160 + }
20.1161 + case PROP_GMYTHTV_LIVE:
20.1162 + g_value_set_boolean (value, mythtvsrc->live_tv);
20.1163 + break;
20.1164 + case PROP_GMYTHTV_ENABLE_TIMING_POSITION:
20.1165 + g_value_set_boolean (value, mythtvsrc->enable_timing_position);
20.1166 + break;
20.1167 + case PROP_GMYTHTV_LIVE_CHAINID:
20.1168 + {
20.1169 + g_value_set_string (value, mythtvsrc->live_chain_id);
20.1170 + break;
20.1171 + }
20.1172 + case PROP_GMYTHTV_CHANNEL_NUM:
20.1173 + {
20.1174 + g_value_set_string (value, mythtvsrc->channel_name);
20.1175 + break;
20.1176 + }
20.1177 + case PROP_GMYTHTV_MAX_TRY:
20.1178 + {
20.1179 + g_value_set_int (value, mythtvsrc->max_try);
20.1180 + break;
20.1181 + }
20.1182 +
20.1183 + default:
20.1184 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
20.1185 + break;
20.1186 + }
20.1187 + GST_OBJECT_UNLOCK (mythtvsrc);
20.1188 +}
20.1189 +
20.1190 +static gboolean
20.1191 +plugin_init (GstPlugin * plugin)
20.1192 +{
20.1193 + return gst_element_register (plugin, "mythtvsrc", GST_RANK_NONE,
20.1194 + GST_TYPE_MYTHTV_SRC);
20.1195 +}
20.1196 +
20.1197 +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
20.1198 + GST_VERSION_MINOR,
20.1199 + "mythtv",
20.1200 + "lib MythTV src",
20.1201 + plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
20.1202 +
20.1203 +
20.1204 +/*** GSTURIHANDLER INTERFACE *************************************************/
20.1205 +static guint
20.1206 +gst_mythtv_src_uri_get_type (void)
20.1207 +{
20.1208 + return GST_URI_SRC;
20.1209 +}
20.1210 +
20.1211 +static gchar **
20.1212 +gst_mythtv_src_uri_get_protocols (void)
20.1213 +{
20.1214 + static gchar *protocols[] = { "myth", "myths", NULL };
20.1215 +
20.1216 + return protocols;
20.1217 +}
20.1218 +
20.1219 +static const gchar *
20.1220 +gst_mythtv_src_uri_get_uri (GstURIHandler * handler)
20.1221 +{
20.1222 + GstMythtvSrc *src = GST_MYTHTV_SRC (handler);
20.1223 +
20.1224 + return src->uri_name;
20.1225 +}
20.1226 +
20.1227 +static gboolean
20.1228 +gst_mythtv_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
20.1229 +{
20.1230 + GstMythtvSrc *src = GST_MYTHTV_SRC (handler);
20.1231 +
20.1232 + gchar *protocol;
20.1233 +
20.1234 + protocol = gst_uri_get_protocol (uri);
20.1235 + if ((strcmp (protocol, "myth") != 0) && (strcmp (protocol, "myths") != 0)) {
20.1236 + g_free (protocol);
20.1237 + return FALSE;
20.1238 + }
20.1239 + g_free (protocol);
20.1240 + g_object_set (src, "location", uri, NULL);
20.1241 +
20.1242 + return TRUE;
20.1243 +}
20.1244 +
20.1245 +static void
20.1246 +gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
20.1247 +{
20.1248 + GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
20.1249 +
20.1250 + iface->get_type = gst_mythtv_src_uri_get_type;
20.1251 + iface->get_protocols = gst_mythtv_src_uri_get_protocols;
20.1252 + iface->get_uri = gst_mythtv_src_uri_get_uri;
20.1253 + iface->set_uri = gst_mythtv_src_uri_set_uri;
20.1254 +}
20.1255 +
20.1256 +void
20.1257 +size_header_handler (void *userdata, const char *value)
20.1258 +{
20.1259 + GstMythtvSrc *src = GST_MYTHTV_SRC (userdata);
20.1260 +
20.1261 + GST_DEBUG_OBJECT (src, "content size = %lld bytes", src->content_size);
20.1262 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/gst-gmyth/mythsrc/gstmythtvsrc.h Tue May 01 16:04:02 2007 +0100
21.3 @@ -0,0 +1,133 @@
21.4 +/* GStreamer
21.5 + * Copyright (C) <2006> Rosfran Borges <rosfran.borges@indt.org.br>
21.6 + *
21.7 + * This library is free software; you can redistribute it and/or
21.8 + * modify it under the terms of the GNU Library General Public
21.9 + * License as published by the Free Software Foundation; either
21.10 + * version 2 of the License, or (at your option) any later version.
21.11 + *
21.12 + * This library is distributed in the hope that it will be useful,
21.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21.15 + * Library General Public License for more details.
21.16 + *
21.17 + * You should have received a copy of the GNU Library General Public
21.18 + * License along with this library; if not, write to the
21.19 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21.20 + * Boston, MA 02111-1307, USA.
21.21 + */
21.22 +
21.23 +#ifndef __GST_MYTHTV_SRC_H__
21.24 +#define __GST_MYTHTV_SRC_H__
21.25 +
21.26 +#include <gst/gst.h>
21.27 +#include <gst/base/gstbasesrc.h>
21.28 +#include <gst/base/gstpushsrc.h>
21.29 +#include <stdio.h>
21.30 +
21.31 +#include <gmyth/gmyth_socket.h>
21.32 +#include <gmyth/gmyth_file.h>
21.33 +#include <gmyth/gmyth_file_transfer.h>
21.34 +#include <gmyth/gmyth_file_local.h>
21.35 +#include <gmyth/gmyth_livetv.h>
21.36 +#include <gmyth/gmyth_backendinfo.h>
21.37 +
21.38 +G_BEGIN_DECLS
21.39 +
21.40 +#define GST_TYPE_MYTHTV_SRC \
21.41 + (gst_mythtv_src_get_type())
21.42 +#define GST_MYTHTV_SRC(obj) \
21.43 + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MYTHTV_SRC,GstMythtvSrc))
21.44 +#define GST_MYTHTV_SRC_CLASS(klass) \
21.45 + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MYTHTV_SRC,GstMythtvSrcClass))
21.46 +#define GST_IS_MYTHTV_SRC(obj) \
21.47 + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MYTHTV_SRC))
21.48 +#define GST_IS_MYTHTV_SRC_CLASS(klass) \
21.49 + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MYTHTV_SRC))
21.50 +
21.51 +typedef struct _GstMythtvSrc GstMythtvSrc;
21.52 +typedef struct _GstMythtvSrcClass GstMythtvSrcClass;
21.53 +
21.54 +typedef enum {
21.55 + GST_MYTHTV_SRC_FILE_TRANSFER,
21.56 + GST_MYTHTV_SRC_NEXT_PROGRAM_CHAIN,
21.57 + GST_MYTHTV_SRC_INVALID_DATA
21.58 +} GstMythtvState;
21.59 +
21.60 +struct _GstMythtvSrc {
21.61 + GstPushSrc element;
21.62 +
21.63 + /* MythFileTransfer */
21.64 + GMythFile *file;
21.65 +
21.66 + GMythLiveTV *spawn_livetv;
21.67 +
21.68 + GMythBackendInfo *backend_info;
21.69 +
21.70 + GstMythtvState state;
21.71 +
21.72 + gchar *uri_name;
21.73 + gchar *user_agent;
21.74 +
21.75 + gchar *live_chain_id;
21.76 +
21.77 + gint mythtv_version;
21.78 +
21.79 + gint64 content_size;
21.80 +
21.81 + gint64 prev_content_size;
21.82 +
21.83 + gint64 content_size_last;
21.84 +
21.85 + guint64 bytes_read;
21.86 +
21.87 + gint64 read_offset;
21.88 +
21.89 + gint buffer_remain;
21.90 +
21.91 + gboolean eos;
21.92 +
21.93 + gboolean do_start;
21.94 +
21.95 + gboolean unique_setup;
21.96 +
21.97 + gboolean live_tv;
21.98 +
21.99 + gboolean enable_timing_position;
21.100 +
21.101 + gint live_tv_id;
21.102 +
21.103 + gchar* channel_name;
21.104 +
21.105 + guint mode;
21.106 +
21.107 + /* MythTV capabilities */
21.108 + GstCaps *mythtv_caps;
21.109 +
21.110 + GByteArray *bytes_queue;
21.111 +
21.112 +#ifndef GST_DISABLE_GST_DEBUG
21.113 + /* enable Myth TV debug messages */
21.114 + gboolean mythtv_msgs_dbg;
21.115 +#endif
21.116 +
21.117 + gboolean update_prog_chain;
21.118 +
21.119 + /* stablish a maximum iteration value to the IS_RECORDING message */
21.120 + guint wait_to_transfer;
21.121 +
21.122 + /* max try number to get freerecorder */
21.123 + gint max_try;
21.124 + gint try_number;
21.125 +
21.126 +};
21.127 +
21.128 +struct _GstMythtvSrcClass {
21.129 + GstPushSrcClass parent_class;
21.130 +};
21.131 +
21.132 +GType gst_mythtv_src_get_type (void);
21.133 +
21.134 +G_END_DECLS
21.135 +
21.136 +#endif /* __GST_MYTHTV_SRC_H__ */
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/gst-gmyth/nuvdemux/Makefile.am Tue May 01 16:04:02 2007 +0100
22.3 @@ -0,0 +1,22 @@
22.4 +plugin_LTLIBRARIES = libgstnuvdemux.la
22.5 +
22.6 +libgstnuvdemux_la_SOURCES = \
22.7 + gstnuvdemux.c
22.8 +
22.9 +libgstnuvdemux_la_CFLAGS = \
22.10 + $(GST_CFLAGS) \
22.11 + $(GST_BASE_CFLAGS) \
22.12 + $(GST_PLUGINS_BASE_CFLAGS)
22.13 +
22.14 +libgstnuvdemux_la_LIBADD = \
22.15 + $(GST_LIBS_LIBS)
22.16 +
22.17 +libgstnuvdemux_la_LDFLAGS = \
22.18 + $(GST_LIBS) \
22.19 + $(GST_PLUGIN_LDFLAGS) \
22.20 + $(GST_BASE_LIBS) \
22.21 + $(GST_PLUGINS_BASE_LIBS)
22.22 +
22.23 +noinst_HEADERS = \
22.24 + gstnuvdemux.h
22.25 +
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/gst-gmyth/nuvdemux/gstnuvdemux.c Tue May 01 16:04:02 2007 +0100
23.3 @@ -0,0 +1,1677 @@
23.4 +/* GStreamer
23.5 + * Copyright (C) <2006> Renato Araujo Oliveira Filho <renato.filho@indt.org.br>
23.6 + * Rosfran Borges <rosfran.borges@indt.org.br>
23.7 + *
23.8 + * This library is free software; you can redistribute it and/or
23.9 + * modify it under the terms of the GNU Library General Public
23.10 + * License as published by the Free Software Foundation; either
23.11 + * version 2 of the License, or (at your option) any later version.
23.12 + *
23.13 + * This library is distributed in the hope that it will be useful,
23.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23.16 + * Library General Public License for more details.
23.17 + *
23.18 + * You should have received a copy of the GNU Library General Public
23.19 + * License along with this library; if not, write to the
23.20 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23.21 + * Boston, MA 02111-1307, USA.
23.22 + */
23.23 +/* Element-Checklist-Version: 5 */
23.24 +
23.25 +/**
23.26 + * SECTION:element-nuvdemux
23.27 + *
23.28 + * <refsect2>
23.29 + * <para>
23.30 + * Demuxes an .nuv file into raw or compressed audio and/or video streams.
23.31 + * </para>
23.32 + * <para>
23.33 + * This element currently only supports pull-based scheduling.
23.34 + * </para>
23.35 + * <title>Example launch line</title>
23.36 + * <para>
23.37 + * <programlisting>
23.38 + * gst-launch filesrc test.nuv ! nuvdemux name=demux demux.audio_00 ! decodebin ! audioconvert ! audioresample ! autoaudiosink demux.video_00 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! autovideosink
23.39 + * </programlisting>
23.40 + * Play (parse and decode) an .nuv file and try to output it to
23.41 + * an automatically detected soundcard and videosink. If the NUV file contains
23.42 + * compressed audio or video data, this will only work if you have the
23.43 + * right decoder elements/plugins installed.
23.44 + * </para>
23.45 + * </refsect2>
23.46 + *
23.47 + */
23.48 +
23.49 +#ifdef HAVE_CONFIG_H
23.50 +#include "config.h"
23.51 +#endif
23.52 +
23.53 +#include <gst/gst.h>
23.54 +#include <gst/gsterror.h>
23.55 +#include <gst/gstplugin.h>
23.56 +#include <string.h>
23.57 +#include <math.h>
23.58 +
23.59 +#include "glib/gi18n.h"
23.60 +#include "gstnuvdemux.h"
23.61 +
23.62 +#define GST_NUV_DEMUX_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_NUV_DEMUX, GstNuvDemuxPrivate))
23.63 +
23.64 +GST_DEBUG_CATEGORY_STATIC (nuvdemux_debug);
23.65 +#define GST_CAT_DEFAULT nuvdemux_debug
23.66 +#define GST_FLOW_ERROR_NO_DATA -101
23.67 +#define GST_FLOW_ERROR_EOS -102
23.68 +
23.69 +enum
23.70 +{
23.71 + NUV_PUSH_MODE = 0,
23.72 + NUV_PULL_MODE
23.73 +};
23.74 +
23.75 +GST_DEBUG_CATEGORY_EXTERN (GST_CAT_EVENT);
23.76 +
23.77 +static const GstElementDetails gst_nuv_demux_details =
23.78 +GST_ELEMENT_DETAILS ("Nuv demuxer",
23.79 + "Codec/Demuxer",
23.80 + "Demultiplex a .nuv file into audio and video",
23.81 + "Renato Araujo Oliveira Filho <renato.filho@indt.org.br>,"
23.82 + "Rosfran Borges <rosfran.borges@indt.org.br>");
23.83 +
23.84 +
23.85 +/* file header */
23.86 +typedef struct
23.87 +{
23.88 + gchar id[12]; /* "NuppelVideo\0" or "MythTVVideo\0" */
23.89 + gchar version[5]; /* "x.xx\0" */
23.90 +
23.91 + gint i_width;
23.92 + gint i_height;
23.93 + gint i_width_desired;
23.94 + gint i_height_desired;
23.95 +
23.96 + gchar i_mode; /* P progressive, I interlaced */
23.97 +
23.98 + gdouble d_aspect; /* 1.0 squared pixel */
23.99 + gdouble d_fps;
23.100 + //fps num/denom
23.101 + gint i_fpsn;
23.102 + gint i_fpsd;
23.103 +
23.104 + gint i_video_blocks; /* 0 no video, -1 unknown */
23.105 + gint i_audio_blocks;
23.106 + gint i_text_blocks;
23.107 +
23.108 + gint i_keyframe_distance;
23.109 +
23.110 +} nuv_header;
23.111 +
23.112 +/* frame header */
23.113 +typedef struct
23.114 +{
23.115 + gchar i_type; /* A: audio, V: video, S: sync; T: test
23.116 + R: Seekpoint (string:RTjjjjjjjj)
23.117 + D: Extra data for codec */
23.118 + gchar i_compression; /* V: 0 uncompressed
23.119 + 1 RTJpeg
23.120 + 2 RTJpeg+lzo
23.121 + N black frame
23.122 + L copy last
23.123 + A: 0 uncompressed (44100 1-bits, 2ch)
23.124 + 1 lzo
23.125 + 2 layer 2
23.126 + 3 layer 3
23.127 + F flac
23.128 + S shorten
23.129 + N null frame loudless
23.130 + L copy last
23.131 + S: B audio and vdeo sync point
23.132 + A audio sync info (timecode == effective
23.133 + dsp frequency*100)
23.134 + V next video sync (timecode == next video
23.135 + frame num)
23.136 + S audio,video,text correlation */
23.137 + gchar i_keyframe; /* 0 keyframe, else no no key frame */
23.138 + guint8 i_filters; /* 0x01: gauss 5 pixel (8,2,2,2,2)/16
23.139 + 0x02: gauss 5 pixel (8,1,1,1,1)/12
23.140 + 0x04: cartoon filter */
23.141 +
23.142 + gint32 i_timecode; /* ms */
23.143 +
23.144 + gint i_length; /* V,A,T: length of following data
23.145 + S: length of packet correl */
23.146 +} nuv_frame_header;
23.147 +
23.148 +
23.149 +/* FIXME Not sure of this one */
23.150 +typedef struct
23.151 +{
23.152 + gint i_version;
23.153 + guint32 i_video_fcc;
23.154 +
23.155 + guint32 i_audio_fcc;
23.156 + gint i_audio_sample_rate;
23.157 + gint i_audio_bits_per_sample;
23.158 + gint i_audio_channels;
23.159 + gint i_audio_compression_ratio;
23.160 + gint i_audio_quality;
23.161 + gint i_rtjpeg_quality;
23.162 + gint i_rtjpeg_luma_filter;
23.163 + gint i_rtjpeg_chroma_filter;
23.164 + gint i_lavc_bitrate;
23.165 + gint i_lavc_qmin;
23.166 + gint i_lavc_qmax;
23.167 + gint i_lavc_maxqdiff;
23.168 + gint64 i_seekable_offset;
23.169 + gint64 i_keyframe_adjust_offset;
23.170 +
23.171 +} nuv_extended_header;
23.172 +
23.173 +typedef struct
23.174 +{
23.175 + gint64 timecode;
23.176 + gint64 offset;
23.177 +
23.178 +} frame_index_data;
23.179 +
23.180 +typedef enum {
23.181 + GST_NUV_DEMUX_START,
23.182 + GST_NUV_DEMUX_HEADER_DATA,
23.183 + GST_NUV_DEMUX_EXTRA_DATA,
23.184 + GST_NUV_DEMUX_MPEG_DATA,
23.185 + GST_NUV_DEMUX_EXTEND_HEADER,
23.186 + GST_NUV_DEMUX_EXTEND_HEADER_DATA,
23.187 + GST_NUV_DEMUX_INDEX_CREATE,
23.188 + GST_NUV_DEMUX_FRAME_HEADER,
23.189 + GST_NUV_DEMUX_MOVI,
23.190 + GST_NUV_DEMUX_INVALID_DATA
23.191 +} GstNuvDemuxState;
23.192 +
23.193 +struct _GstNuvDemuxPrivate {
23.194 + /* used for indicate the mode */
23.195 + guint mode;
23.196 +
23.197 + /* used on push mode */
23.198 + GstAdapter *adapter;
23.199 +
23.200 + /* pads */
23.201 + GstPad *sinkpad;
23.202 + GstPad *src_video_pad;
23.203 + GstPad *src_audio_pad;
23.204 +
23.205 + /* Flow control */
23.206 + GstFlowReturn last_video_return;
23.207 + GstFlowReturn last_audio_return;
23.208 + gboolean more_data;
23.209 + gboolean eos;
23.210 +
23.211 + /* NUV decoding state */
23.212 + GstNuvDemuxState state;
23.213 + guint64 offset;
23.214 +
23.215 + /* duration information */
23.216 + guint64 duration_bytes;
23.217 + guint64 duration_time;
23.218 + guint64 segment_stop;
23.219 + guint64 segment_start;
23.220 +
23.221 + /* segment control info */
23.222 + gboolean new_audio_segment;
23.223 + gboolean new_video_segment;
23.224 +
23.225 + /* Mpeg ExtraData */
23.226 + guint64 mpeg_data_size;
23.227 + GstBuffer *mpeg_buffer;
23.228 +
23.229 + /* Headers */
23.230 + nuv_header h;
23.231 + nuv_extended_header eh;
23.232 + nuv_frame_header fh;
23.233 +
23.234 + /* anothers info */
23.235 + guint64 header_lengh;
23.236 + gint64 time_start;
23.237 + gint64 time_diff;
23.238 + gint64 time_qos;
23.239 + guint64 last_frame_time;
23.240 + GSList *index;
23.241 +};
23.242 +
23.243 +
23.244 +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
23.245 + GST_PAD_SINK,
23.246 + GST_PAD_ALWAYS,
23.247 + GST_STATIC_CAPS ("video/x-nuv"));
23.248 +
23.249 +static GstStaticPadTemplate audio_src_template =
23.250 +GST_STATIC_PAD_TEMPLATE ("audio_src",
23.251 + GST_PAD_SRC,
23.252 + GST_PAD_SOMETIMES,
23.253 + GST_STATIC_CAPS_ANY);
23.254 +
23.255 +static GstStaticPadTemplate video_src_template =
23.256 +GST_STATIC_PAD_TEMPLATE ("video_src",
23.257 + GST_PAD_SRC,
23.258 + GST_PAD_SOMETIMES,
23.259 + GST_STATIC_CAPS_ANY);
23.260 +
23.261 +static void gst_nuv_demux_dispose (GObject * object);
23.262 +static void gst_nuv_demux_finalize (GObject * object);
23.263 +static GstStateChangeReturn gst_nuv_demux_change_state (GstElement * element,
23.264 + GstStateChange transition);
23.265 +static void gst_nuv_demux_loop (GstPad * pad);
23.266 +static GstFlowReturn gst_nuv_demux_chain (GstPad * pad, GstBuffer * buf);
23.267 +static GstFlowReturn gst_nuv_demux_play (GstPad * pad);
23.268 +static gboolean gst_nuv_demux_sink_activate_pull (GstPad * sinkpad,
23.269 + gboolean active);
23.270 +static gboolean gst_nuv_demux_sink_activate_push (GstPad * pad,
23.271 + gboolean active);
23.272 +static gboolean gst_nuv_demux_sink_activate (GstPad * sinkpad);
23.273 +//static gboolean gst_nuv_demux_sink_event (GstPad *pad, GstEvent *event);
23.274 +static gboolean gst_nuv_demux_srcpad_event (GstPad * pad, GstEvent * event);
23.275 +static frame_index_data * gst_nuv_demux_do_seek_index (GstNuvDemux *nuv, gint64 seek_pos,
23.276 + gint64 segment_stop, GstFormat format);
23.277 +
23.278 +
23.279 +
23.280 +static GstFlowReturn gst_nuv_demux_read_bytes (GstNuvDemux * nuv, guint64 size,
23.281 + gboolean move, GstBuffer ** buffer);
23.282 +static void gst_nuv_demux_reset (GstNuvDemux * nuv);
23.283 +static void gst_nuv_demux_destoy_src_pad (GstNuvDemux * nuv);
23.284 +static void gst_nuv_demux_send_eos (GstNuvDemux * nuv);
23.285 +static void gst_nuv_demux_create_seek_index (GstNuvDemux * nuv);
23.286 +
23.287 +
23.288 +#if (GST_VERSION_MINOR == 10) && (GST_VERSION_MICRO < 6)
23.289 +GstBuffer * gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes);
23.290 +#endif
23.291 +
23.292 +
23.293 +GST_BOILERPLATE (GstNuvDemux, gst_nuv_demux, GstElement, GST_TYPE_ELEMENT);
23.294 +
23.295 +/******************************************************************************
23.296 + * Utils function
23.297 + ******************************************************************************/
23.298 +#if G_BYTE_ORDER == G_BIG_ENDIAN
23.299 +static inline gdouble
23.300 +_gdouble_swap_le_be (gdouble * d)
23.301 +{
23.302 + union
23.303 + {
23.304 + guint64 i;
23.305 + gdouble d;
23.306 + } u;
23.307 +
23.308 + u.d = *d;
23.309 + u.i = GUINT64_SWAP_LE_BE (u.i);
23.310 + return u.d;
23.311 +}
23.312 +
23.313 +#define READ_DOUBLE_FROM_LE(d) (_gdouble_swap_le_be((gdouble* ) d))
23.314 +#else /* G_BYTE_ORDER != G_BIG_ENDIAN */
23.315 +#define READ_DOUBLE_FROM_LE(d) *((gdouble* ) (d))
23.316 +#endif /* G_BYTE_ORDER != G_BIG_ENDIAN */
23.317 +
23.318 +static void
23.319 +double2fraction (double in, int *num, int *denom)
23.320 +{
23.321 + if (in == 29.97) {
23.322 + *num = 30000;
23.323 + *denom = 1001;
23.324 + } else if (in == 23.976) {
23.325 + *num = 24000;
23.326 + *denom = 1001;
23.327 + } else {
23.328 + *denom = 1;
23.329 + while (in - floor(in) >= 0.1) {
23.330 + *denom *= 10;
23.331 + in *= 10.0;
23.332 + }
23.333 + *num = (int)floor(in);
23.334 + }
23.335 +}
23.336 +
23.337 +/* GObject Functions */
23.338 +
23.339 +static void
23.340 +gst_nuv_demux_base_init (gpointer klass)
23.341 +{
23.342 + GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
23.343 +
23.344 + gst_element_class_add_pad_template (element_class,
23.345 + gst_static_pad_template_get (&audio_src_template));
23.346 +
23.347 + gst_element_class_add_pad_template (element_class,
23.348 + gst_static_pad_template_get (&video_src_template));
23.349 +
23.350 + gst_element_class_add_pad_template (element_class,
23.351 + gst_static_pad_template_get (&sink_template));
23.352 + gst_element_class_set_details (element_class, &gst_nuv_demux_details);
23.353 +}
23.354 +
23.355 +static void
23.356 +gst_nuv_demux_class_init (GstNuvDemuxClass * klass)
23.357 +{
23.358 + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
23.359 + GObjectClass *gobject_class = (GObjectClass *) klass;
23.360 +
23.361 + GST_DEBUG_CATEGORY_INIT (nuvdemux_debug, "nuvdemux",
23.362 + 0, "Demuxer for NUV streams");
23.363 +
23.364 + parent_class = g_type_class_peek_parent (klass);
23.365 +
23.366 + gobject_class->dispose = gst_nuv_demux_dispose;
23.367 + gobject_class->finalize = gst_nuv_demux_finalize;
23.368 + gstelement_class->change_state = gst_nuv_demux_change_state;
23.369 +
23.370 + g_type_class_add_private (gobject_class, sizeof (GstNuvDemuxPrivate));
23.371 +}
23.372 +
23.373 +static void
23.374 +gst_nuv_demux_init (GstNuvDemux * nuv, GstNuvDemuxClass * nuv_class)
23.375 +{
23.376 + nuv->priv = GST_NUV_DEMUX_GET_PRIVATE (nuv);
23.377 + nuv->priv->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
23.378 +
23.379 + /* creating adapter */
23.380 + nuv->priv->mode = NUV_PUSH_MODE;
23.381 + nuv->priv->adapter = gst_adapter_new ();
23.382 +
23.383 + nuv->priv->new_audio_segment = TRUE;
23.384 + nuv->priv->new_video_segment = TRUE;
23.385 +
23.386 + gst_pad_set_activate_function (nuv->priv->sinkpad, gst_nuv_demux_sink_activate);
23.387 + gst_pad_set_activatepull_function (nuv->priv->sinkpad,
23.388 + gst_nuv_demux_sink_activate_pull);
23.389 + gst_pad_set_activatepush_function (nuv->priv->sinkpad,
23.390 + gst_nuv_demux_sink_activate_push);
23.391 + gst_pad_set_chain_function (nuv->priv->sinkpad,
23.392 + GST_DEBUG_FUNCPTR (gst_nuv_demux_chain));
23.393 +/*
23.394 + gst_pad_set_event_function (nuv->priv->sinkpad,
23.395 + gst_nuv_demux_sink_event);
23.396 +*/
23.397 +
23.398 + gst_element_add_pad (GST_ELEMENT (nuv), nuv->priv->sinkpad);
23.399 +
23.400 +}
23.401 +
23.402 +static void
23.403 +gst_nuv_demux_dispose (GObject * object)
23.404 +{
23.405 + GstNuvDemux *nuv = GST_NUV_DEMUX (object);
23.406 +
23.407 +
23.408 + if (nuv->priv->mpeg_buffer != NULL) {
23.409 + gst_buffer_unref (nuv->priv->mpeg_buffer);
23.410 + }
23.411 +
23.412 + gst_nuv_demux_reset (GST_NUV_DEMUX (object));
23.413 + gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (object));
23.414 +
23.415 + if (nuv->priv->adapter != NULL) {
23.416 + gst_object_unref (nuv->priv->adapter);
23.417 + }
23.418 +}
23.419 +
23.420 +static void
23.421 +gst_nuv_demux_finalize (GObject * object)
23.422 +{
23.423 + G_OBJECT_CLASS (parent_class)->finalize (object);
23.424 +}
23.425 +
23.426 +
23.427 +/* HeaderLoad:
23.428 + */
23.429 +static GstFlowReturn
23.430 +gst_nuv_demux_header_load (GstNuvDemux * nuv, nuv_header *h)
23.431 +{
23.432 + GstBuffer *buffer = NULL;
23.433 + GstFlowReturn res = gst_nuv_demux_read_bytes (nuv, 72, TRUE, &buffer);
23.434 +
23.435 + if ((res != GST_FLOW_OK) || (buffer == NULL)) {
23.436 + goto done;
23.437 + }
23.438 +
23.439 + memcpy (h->id, buffer->data, 12);
23.440 + memcpy (h->version, buffer->data + 12, 5);
23.441 + h->i_width = GST_READ_UINT32_LE (&buffer->data[20]);
23.442 + h->i_height = GST_READ_UINT32_LE (&buffer->data[24]);
23.443 + h->i_width_desired = GST_READ_UINT32_LE (&buffer->data[28]);
23.444 + h->i_height_desired = GST_READ_UINT32_LE (&buffer->data[32]);
23.445 + h->i_mode = GPOINTER_TO_INT (buffer->data[36]);
23.446 + h->d_aspect = READ_DOUBLE_FROM_LE (&buffer->data[40]);
23.447 + h->d_fps = READ_DOUBLE_FROM_LE (&buffer->data[48]);
23.448 + /* get the num and denom values from fps */
23.449 + double2fraction (h->d_fps, &h->i_fpsn, &h->i_fpsd);
23.450 + h->i_video_blocks = GST_READ_UINT32_LE (&buffer->data[56]);
23.451 + h->i_audio_blocks = GST_READ_UINT32_LE (&buffer->data[60]);
23.452 + h->i_text_blocks = GST_READ_UINT32_LE (&buffer->data[64]);
23.453 + h->i_keyframe_distance = GST_READ_UINT32_LE (&buffer->data[68]);
23.454 +
23.455 + GST_DEBUG_OBJECT (nuv,
23.456 + "nuv: h=%s v=%s %dx%d a=%f fps=%f v=%d a=%d t=%d kfd=%d", h->id,
23.457 + h->version, h->i_width, h->i_height, h->d_aspect, h->d_fps,
23.458 + h->i_video_blocks, h->i_audio_blocks, h->i_text_blocks,
23.459 + h->i_keyframe_distance);
23.460 +
23.461 +done:
23.462 + if (buffer != NULL) {
23.463 + gst_buffer_unref (buffer);
23.464 + buffer = NULL;
23.465 + }
23.466 + return res;
23.467 +}
23.468 +
23.469 +static GstFlowReturn
23.470 +gst_nuv_demux_stream_header_data (GstNuvDemux * nuv)
23.471 +{
23.472 + GstFlowReturn res;
23.473 +
23.474 + res = gst_nuv_demux_header_load (nuv, &nuv->priv->h);
23.475 + if (res == GST_FLOW_OK)
23.476 + nuv->priv->state = GST_NUV_DEMUX_EXTRA_DATA;
23.477 + return res;
23.478 +}
23.479 +
23.480 +/*
23.481 + * Read NUV file tag
23.482 + */
23.483 +static GstFlowReturn
23.484 +gst_nuv_demux_stream_file_header (GstNuvDemux * nuv)
23.485 +{
23.486 + GstFlowReturn res = GST_FLOW_OK;
23.487 + GstBuffer *file_header = NULL;
23.488 +
23.489 + res = gst_nuv_demux_read_bytes (nuv, 12, FALSE, &file_header);
23.490 + if (res == GST_FLOW_OK) {
23.491 + if (strncmp ((gchar *) file_header->data, "MythTVVideo", 11) ||
23.492 + strncmp ((gchar *) file_header->data, "NuppelVideo", 11)) {
23.493 + nuv->priv->state = GST_NUV_DEMUX_HEADER_DATA;
23.494 + } else {
23.495 + GST_DEBUG_OBJECT (nuv, "error parsing file header");
23.496 + nuv->priv->state = GST_NUV_DEMUX_INVALID_DATA;
23.497 + res = GST_FLOW_ERROR;
23.498 + }
23.499 + }
23.500 +
23.501 + if (file_header != NULL) {
23.502 + gst_buffer_unref (file_header);
23.503 + file_header = NULL;
23.504 + }
23.505 + return res;
23.506 +}
23.507 +
23.508 +/* FrameHeaderLoad:
23.509 + */
23.510 +static GstFlowReturn
23.511 +gst_nuv_demux_frame_header_load (GstNuvDemux * nuv, nuv_frame_header *h)
23.512 +{
23.513 + unsigned char *data;
23.514 + GstBuffer *buf = NULL;
23.515 +
23.516 + GstFlowReturn res = gst_nuv_demux_read_bytes (nuv, 12, TRUE, &buf);
23.517 +
23.518 + if ((res != GST_FLOW_OK) || (buf == NULL)) {
23.519 + goto done;
23.520 + }
23.521 +
23.522 + data = buf->data;
23.523 +
23.524 + h->i_type = GPOINTER_TO_INT (data[0]);
23.525 + h->i_compression = GPOINTER_TO_INT (data[1]);
23.526 + h->i_keyframe = GPOINTER_TO_INT (data[2]);
23.527 + h->i_filters = GPOINTER_TO_INT (data[3]);
23.528 + h->i_timecode = GST_READ_UINT32_LE (&data[4]);
23.529 + h->i_length = GST_READ_UINT32_LE (&data[8]);
23.530 +
23.531 + GST_DEBUG_OBJECT (nuv, "frame hdr: t=%c c=%c k=%d f=0x%x timecode=%d l=%d",
23.532 + h->i_type,
23.533 + h->i_compression ? h->i_compression : ' ',
23.534 + h->i_keyframe ? h->i_keyframe : ' ',
23.535 + h->i_filters, h->i_timecode, h->i_length);
23.536 +
23.537 +done:
23.538 + if (buf != NULL) {
23.539 + gst_buffer_unref (buf);
23.540 + buf = NULL;
23.541 + }
23.542 +
23.543 + return res;
23.544 +}
23.545 +
23.546 +static GstFlowReturn
23.547 +gst_nuv_demux_extended_header_load (GstNuvDemux * nuv,
23.548 + nuv_extended_header * h)
23.549 +{
23.550 + unsigned char *data;
23.551 + GstBuffer *buff = NULL;
23.552 +
23.553 + GstFlowReturn res = gst_nuv_demux_read_bytes (nuv, 512, TRUE, &buff);
23.554 +
23.555 + if ((res != GST_FLOW_OK) || (buff == NULL)) {
23.556 + goto done;
23.557 + }
23.558 +
23.559 + data = buff->data;
23.560 + h->i_version = GST_READ_UINT32_LE (&data[0]);
23.561 + h->i_video_fcc = GST_MAKE_FOURCC (data[4], data[5], data[6], data[7]);
23.562 + h->i_audio_fcc = GST_MAKE_FOURCC (data[8], data[9], data[10], data[11]);
23.563 + h->i_audio_sample_rate = GST_READ_UINT32_LE (&data[12]);
23.564 + h->i_audio_bits_per_sample = GST_READ_UINT32_LE (&data[16]);
23.565 + h->i_audio_channels = GST_READ_UINT32_LE (&data[20]);
23.566 + h->i_audio_compression_ratio = GST_READ_UINT32_LE (&data[24]);
23.567 + h->i_audio_quality = GST_READ_UINT32_LE (&data[28]);
23.568 + h->i_rtjpeg_quality = GST_READ_UINT32_LE (&data[32]);
23.569 + h->i_rtjpeg_luma_filter = GST_READ_UINT32_LE (&data[36]);
23.570 + h->i_rtjpeg_chroma_filter = GST_READ_UINT32_LE (&data[40]);
23.571 + h->i_lavc_bitrate = GST_READ_UINT32_LE (&data[44]);
23.572 + h->i_lavc_qmin = GST_READ_UINT32_LE (&data[48]);
23.573 + h->i_lavc_qmin = GST_READ_UINT32_LE (&data[52]);
23.574 + h->i_lavc_maxqdiff = GST_READ_UINT32_LE (&data[56]);
23.575 + h->i_seekable_offset = GST_READ_UINT64_LE (&data[60]);
23.576 + h->i_keyframe_adjust_offset = GST_READ_UINT64_LE (&data[68]);
23.577 +
23.578 + GST_DEBUG_OBJECT (nuv,
23.579 + "ex hdr: v=%d vffc=%4.4s afcc=%4.4s %dHz %dbits ach=%d acr=%d aq=%d"
23.580 + "rtjpeg q=%d lf=%d lc=%d lavc br=%d qmin=%d qmax=%d maxqdiff=%d seekableoff=%lld keyfao=%lld",
23.581 + h->i_version, (gchar *) & h->i_video_fcc, (gchar *) & h->i_audio_fcc,
23.582 + h->i_audio_sample_rate, h->i_audio_bits_per_sample, h->i_audio_channels,
23.583 + h->i_audio_compression_ratio, h->i_audio_quality, h->i_rtjpeg_quality,
23.584 + h->i_rtjpeg_luma_filter, h->i_rtjpeg_chroma_filter, h->i_lavc_bitrate,
23.585 + h->i_lavc_qmin, h->i_lavc_qmax, h->i_lavc_maxqdiff, h->i_seekable_offset,
23.586 + h->i_keyframe_adjust_offset);
23.587 +
23.588 +done:
23.589 + if (buff != NULL) {
23.590 + gst_buffer_unref (buff);
23.591 + buff = NULL;
23.592 + }
23.593 + return res;
23.594 +}
23.595 +
23.596 +
23.597 +/* Query Functions */
23.598 +static const GstQueryType *
23.599 +gst_nuv_demux_get_src_query_types (GstPad * pad)
23.600 +{
23.601 + static const GstQueryType src_types[] = {
23.602 + GST_QUERY_POSITION,
23.603 + GST_QUERY_DURATION,
23.604 + 0
23.605 + };
23.606 +
23.607 + return src_types;
23.608 +}
23.609 +
23.610 +static gboolean
23.611 +gst_nuv_demux_handle_src_query (GstPad * pad, GstQuery * query)
23.612 +{
23.613 + gboolean res = FALSE;
23.614 + GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (pad));
23.615 +
23.616 + switch (GST_QUERY_TYPE (query)) {
23.617 + case GST_QUERY_POSITION:
23.618 + if (GST_CLOCK_TIME_IS_VALID (nuv->priv->last_frame_time)) {
23.619 + gst_query_set_position (query, GST_FORMAT_TIME, nuv->priv->last_frame_time);
23.620 + res = TRUE;
23.621 + }
23.622 + break;
23.623 + case GST_QUERY_DURATION:
23.624 + {
23.625 + if (nuv->priv->duration_time != GST_CLOCK_TIME_NONE) {
23.626 + gst_query_set_duration (query, GST_FORMAT_TIME, nuv->priv->duration_time);
23.627 + res = TRUE;
23.628 + }
23.629 + }
23.630 + break;
23.631 + default:
23.632 + res = FALSE;
23.633 + break;
23.634 + }
23.635 +
23.636 + gst_object_unref (nuv);
23.637 +
23.638 + return res;
23.639 +}
23.640 +
23.641 +static GstPad*
23.642 +gst_nuv_demux_create_pad (GstNuvDemux *nuv, GstCaps *caps, GstStaticPadTemplate *template, const gchar* name)
23.643 +{
23.644 + GstPad *pad = NULL;
23.645 + pad = gst_pad_new_from_static_template (template, name);
23.646 + gst_pad_set_caps (pad, caps);
23.647 + gst_pad_set_active (pad, TRUE);
23.648 + gst_pad_use_fixed_caps (pad);
23.649 + gst_element_add_pad (GST_ELEMENT (nuv), pad);
23.650 +
23.651 + gst_pad_set_event_function (pad,
23.652 + GST_DEBUG_FUNCPTR (gst_nuv_demux_srcpad_event));
23.653 +
23.654 + gst_pad_set_query_type_function (pad,
23.655 + GST_DEBUG_FUNCPTR (gst_nuv_demux_get_src_query_types));
23.656 +
23.657 + gst_pad_set_query_function (pad,
23.658 + GST_DEBUG_FUNCPTR (gst_nuv_demux_handle_src_query));
23.659 +
23.660 +
23.661 + return pad;
23.662 +}
23.663 +
23.664 +static void
23.665 +gst_nuv_demux_create_pads (GstNuvDemux * nuv)
23.666 +{
23.667 + if (nuv->priv->h.i_video_blocks != 0) {
23.668 + GstCaps *video_caps = NULL;
23.669 +
23.670 + video_caps = gst_caps_new_simple ("video/x-divx",
23.671 + "divxversion", G_TYPE_INT, 4,
23.672 + "width", G_TYPE_INT, nuv->priv->h.i_width,
23.673 + "height", G_TYPE_INT, nuv->priv->h.i_height,
23.674 + "framerate", GST_TYPE_FRACTION, nuv->priv->h.i_fpsn, nuv->priv->h.i_fpsd,
23.675 + "format", GST_TYPE_FOURCC, nuv->priv->eh.i_video_fcc,
23.676 + "pixel-aspect-ratio", GST_TYPE_FRACTION,
23.677 + (gint) (nuv->priv->h.d_aspect * 1000.0f), 1000, NULL);
23.678 +
23.679 + nuv->priv->src_video_pad = gst_nuv_demux_create_pad (nuv, video_caps, &video_src_template, "video_src");
23.680 + gst_caps_unref (video_caps);
23.681 + }
23.682 +
23.683 + if (nuv->priv->h.i_audio_blocks != 0) {
23.684 + GstCaps *audio_caps = NULL;
23.685 +
23.686 + audio_caps = gst_caps_new_simple ("audio/mpeg",
23.687 + "rate", G_TYPE_INT, nuv->priv->eh.i_audio_sample_rate,
23.688 + "format", GST_TYPE_FOURCC, nuv->priv->eh.i_audio_fcc,
23.689 + "channels", G_TYPE_INT, nuv->priv->eh.i_audio_channels,
23.690 + "layer", G_TYPE_INT, 3, // fixme: magic number
23.691 + "mpegversion", G_TYPE_INT, nuv->priv->eh.i_version, NULL);
23.692 +
23.693 + nuv->priv->src_audio_pad = gst_nuv_demux_create_pad (nuv, audio_caps, &audio_src_template, "audio_src");
23.694 + gst_caps_unref (audio_caps);
23.695 + }
23.696 +
23.697 + gst_element_no_more_pads (GST_ELEMENT (nuv));
23.698 +}
23.699 +
23.700 +static gboolean
23.701 +gst_nuv_demux_validate_header (nuv_frame_header *h)
23.702 +{
23.703 + gboolean valid = FALSE;
23.704 + //g_usleep (1 * G_USEC_PER_SEC );
23.705 + switch (h->i_type) {
23.706 +/*
23.707 + case 'V':
23.708 + if (h->i_compression == 0 ||
23.709 + h->i_compression == 1 ||
23.710 + h->i_compression == 2 ||
23.711 + h->i_compression == 'N' ||
23.712 + h->i_compression == 'L') {
23.713 + valid = TRUE;
23.714 + }
23.715 + break;
23.716 + case 'A':
23.717 + if (h->i_compression == 0 ||
23.718 + h->i_compression == 1 ||
23.719 + h->i_compression == 2 ||
23.720 + h->i_compression == 3 ||
23.721 + h->i_compression == 'F' ||
23.722 + h->i_compression == 'S' ||
23.723 + h->i_compression == 'N' ||
23.724 + h->i_compression == 'L') {
23.725 + valid = TRUE;
23.726 + }
23.727 + break;
23.728 + case 'S':
23.729 + if (h->i_compression == 'B' ||
23.730 + h->i_compression == 'A' ||
23.731 + h->i_compression == 'V' ||
23.732 + h->i_compression == 'S') {
23.733 + valid = TRUE;
23.734 + }
23.735 + break;
23.736 +*/
23.737 + case 'A':
23.738 + case 'V':
23.739 + case 'S':
23.740 + case 'R':
23.741 + case 'D':
23.742 + case 'Q':
23.743 + valid = TRUE;
23.744 + break;
23.745 + default:
23.746 + valid = FALSE;
23.747 + }
23.748 +
23.749 + return valid;
23.750 +}
23.751 +
23.752 +static GstFlowReturn
23.753 +gst_nuv_demux_read_head_frame (GstNuvDemux * nuv)
23.754 +{
23.755 + GstFlowReturn ret = GST_FLOW_OK;
23.756 + gboolean valid = FALSE;
23.757 +
23.758 + do {
23.759 + ret = gst_nuv_demux_frame_header_load (nuv, &nuv->priv->fh);
23.760 + if (ret != GST_FLOW_OK) {
23.761 + return ret;
23.762 + }
23.763 +
23.764 + if (gst_nuv_demux_validate_header (&nuv->priv->fh) == TRUE)
23.765 + valid = TRUE;
23.766 +
23.767 + } while (valid == FALSE);
23.768 +
23.769 + nuv->priv->state = GST_NUV_DEMUX_MOVI;
23.770 + return ret;
23.771 +}
23.772 +
23.773 +static gboolean
23.774 +gst_nuv_combine_flow (GstNuvDemux *nuv)
23.775 +{
23.776 + GstFlowReturn ret_video = nuv->priv->last_video_return;
23.777 + GstFlowReturn ret_audio = nuv->priv->last_audio_return;
23.778 +
23.779 + if ((ret_video != GST_FLOW_OK) &&
23.780 + (ret_audio != GST_FLOW_OK))
23.781 + return FALSE;
23.782 +
23.783 + if (GST_FLOW_IS_FATAL (ret_video))
23.784 + return FALSE;
23.785 +
23.786 + if (GST_FLOW_IS_FATAL (ret_audio))
23.787 + return FALSE;
23.788 +
23.789 + return TRUE;
23.790 +}
23.791 +
23.792 +static GstFlowReturn
23.793 +gst_nuv_demux_stream_data (GstNuvDemux * nuv)
23.794 +{
23.795 + GstFlowReturn ret = GST_FLOW_OK;
23.796 + GstPad *pad = NULL;
23.797 + guint64 timestamp;
23.798 + GstBuffer *buf = NULL;
23.799 + nuv_frame_header h;
23.800 +
23.801 + h = nuv->priv->fh;
23.802 +
23.803 + if (h.i_type == 'R') {
23.804 + goto done;
23.805 + }
23.806 +
23.807 + if (h.i_length > 0) {
23.808 + ret = gst_nuv_demux_read_bytes (nuv, h.i_length, TRUE, &buf);
23.809 + if ((ret != GST_FLOW_OK) || (buf == NULL)) {
23.810 + goto done;
23.811 + }
23.812 +
23.813 + if ((h.i_timecode < 0)) {
23.814 + h.i_timecode = 0;
23.815 + //goto done;
23.816 + }
23.817 +
23.818 + timestamp = h.i_timecode * GST_MSECOND;
23.819 + GST_BUFFER_TIMESTAMP (buf) = timestamp;
23.820 + }
23.821 + else {
23.822 + goto done;
23.823 + }
23.824 +
23.825 +
23.826 + switch (h.i_type) {
23.827 + case 'V':
23.828 + {
23.829 + pad = nuv->priv->src_video_pad;
23.830 +
23.831 + if (nuv->priv->new_video_segment) {
23.832 +
23.833 + /* send new segment event*/
23.834 + gst_pad_push_event (nuv->priv->src_video_pad,
23.835 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0,
23.836 + GST_CLOCK_TIME_NONE, 0));
23.837 +
23.838 + if (nuv->priv->time_start == GST_CLOCK_TIME_NONE) {
23.839 + nuv->priv->time_start = timestamp;
23.840 + }
23.841 + nuv->priv->new_video_segment = FALSE;
23.842 + }
23.843 +
23.844 + break;
23.845 + }
23.846 + case 'A':
23.847 + {
23.848 + pad = nuv->priv->src_audio_pad;
23.849 +
23.850 + if (nuv->priv->new_audio_segment) {
23.851 + /* send new segment event*/
23.852 + gst_pad_push_event (nuv->priv->src_audio_pad,
23.853 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0,
23.854 + GST_CLOCK_TIME_NONE, 0));
23.855 +
23.856 + if (nuv->priv->time_start == GST_CLOCK_TIME_NONE) {
23.857 + nuv->priv->time_start = timestamp;
23.858 + }
23.859 + nuv->priv->new_audio_segment = FALSE;
23.860 + }
23.861 +
23.862 + break;
23.863 + }
23.864 + case 'S':
23.865 + {
23.866 + switch (h.i_compression) {
23.867 + case 'V':
23.868 + GST_DEBUG_OBJECT (nuv, "sending new video segment: %d", h.i_timecode);
23.869 + gst_pad_push_event (nuv->priv->src_video_pad,
23.870 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, h.i_timecode * GST_MSECOND,
23.871 + GST_CLOCK_TIME_NONE, 0));
23.872 + break;
23.873 + case 'A':
23.874 + GST_DEBUG_OBJECT (nuv, "sending new audio segment: %d", h.i_timecode);
23.875 + gst_pad_push_event (nuv->priv->src_audio_pad,
23.876 + gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, 0,
23.877 + GST_CLOCK_TIME_NONE, 0));
23.878 + break;
23.879 + default:
23.880 + break;
23.881 + }
23.882 + goto done;
23.883 + }
23.884 + default:
23.885 + break;
23.886 + }
23.887 +
23.888 + if ((buf != NULL) && (pad != NULL)) {
23.889 + /* pushing the buffer */
23.890 + gst_buffer_set_caps (buf, GST_PAD_CAPS (pad));
23.891 + ret = gst_pad_push (pad, buf);
23.892 + buf = NULL;
23.893 +
23.894 + if (ret != GST_FLOW_OK) {
23.895 + GST_WARNING_OBJECT (nuv, "error: %d pushing on srcpad %s", ret, gst_pad_get_name (pad));
23.896 +
23.897 + if (pad == nuv->priv->src_video_pad) {
23.898 + nuv->priv->last_video_return = ret;
23.899 + }
23.900 + else if (pad == nuv->priv->src_audio_pad) {
23.901 + nuv->priv->last_audio_return = ret;
23.902 + }
23.903 +
23.904 + /* verify anothers flow if is necessary stop task */
23.905 + if (gst_nuv_combine_flow (nuv) != FALSE) {
23.906 + ret = GST_FLOW_OK;
23.907 + } else {
23.908 + GST_WARNING_OBJECT (nuv, "error: on push");
23.909 + }
23.910 +
23.911 + }
23.912 + }
23.913 +
23.914 +done:
23.915 + if (buf != NULL) {
23.916 + gst_buffer_unref (buf);
23.917 + buf = NULL;
23.918 + }
23.919 + if (ret == GST_FLOW_OK) {
23.920 + nuv->priv->state = GST_NUV_DEMUX_FRAME_HEADER;
23.921 + memset (&nuv->priv->fh, 0, sizeof (nuv->priv->fh));
23.922 + }
23.923 + return ret;
23.924 +}
23.925 +
23.926 +static GstFlowReturn
23.927 +gst_nuv_demux_stream_mpeg_data (GstNuvDemux * nuv)
23.928 +{
23.929 + GstFlowReturn ret = GST_FLOW_OK;
23.930 +
23.931 + /* ffmpeg extra data */
23.932 + ret = gst_nuv_demux_read_bytes (nuv, nuv->priv->mpeg_data_size, TRUE,
23.933 + &nuv->priv->mpeg_buffer);
23.934 + if ((ret != GST_FLOW_OK) || (nuv->priv->mpeg_buffer == NULL)) {
23.935 + return ret;
23.936 + }
23.937 +
23.938 + GST_BUFFER_SIZE (nuv->priv->mpeg_buffer) = nuv->priv->mpeg_data_size;
23.939 + nuv->priv->state = GST_NUV_DEMUX_EXTEND_HEADER;
23.940 + return ret;
23.941 +}
23.942 +
23.943 +static GstFlowReturn
23.944 +gst_nuv_demux_stream_extra_data (GstNuvDemux * nuv)
23.945 +{
23.946 + GstFlowReturn ret = GST_FLOW_OK;
23.947 +
23.948 + /* Load 'D' */
23.949 + nuv_frame_header h;
23.950 +
23.951 + ret = gst_nuv_demux_frame_header_load (nuv, &h);
23.952 + if (ret != GST_FLOW_OK)
23.953 + return ret;
23.954 +
23.955 + if (h.i_type != 'D') {
23.956 + GST_WARNING_OBJECT (nuv, "Unsuported rtjpeg");
23.957 + return GST_FLOW_NOT_SUPPORTED;
23.958 + }
23.959 +
23.960 + if (h.i_length > 0) {
23.961 + if (h.i_compression == 'F') {
23.962 + nuv->priv->state = GST_NUV_DEMUX_MPEG_DATA;
23.963 + } else {
23.964 + GST_WARNING_OBJECT (nuv, "only file with extended chunk are supported");
23.965 + return GST_FLOW_NOT_SUPPORTED;
23.966 + }
23.967 + } else {
23.968 + nuv->priv->state = GST_NUV_DEMUX_EXTEND_HEADER;
23.969 + }
23.970 +
23.971 + return ret;
23.972 +}
23.973 +
23.974 +static GstFlowReturn
23.975 +gst_nuv_demux_stream_extend_header_data (GstNuvDemux * nuv)
23.976 +{
23.977 + GstFlowReturn ret = GST_FLOW_OK;
23.978 +
23.979 + ret = gst_nuv_demux_extended_header_load (nuv, &nuv->priv->eh);
23.980 + if (ret != GST_FLOW_OK)
23.981 + return ret;
23.982 +
23.983 + gst_nuv_demux_create_pads (nuv);
23.984 + nuv->priv->state = GST_NUV_DEMUX_INDEX_CREATE;
23.985 + return ret;
23.986 +}
23.987 +
23.988 +static GstFlowReturn
23.989 +gst_nuv_demux_stream_extend_header (GstNuvDemux * nuv)
23.990 +{
23.991 + GstBuffer *buf = NULL;
23.992 + GstFlowReturn res = GST_FLOW_OK;
23.993 +
23.994 + res = gst_nuv_demux_read_bytes (nuv, 1, FALSE, &buf);
23.995 + if ((res != GST_FLOW_OK) || (buf == NULL)) {
23.996 + if (buf != NULL) {
23.997 + gst_buffer_unref (buf);
23.998 + }
23.999 + return res;
23.1000 + }
23.1001 +
23.1002 + if (buf->data[0] == 'X') {
23.1003 + gst_buffer_unref (buf);
23.1004 + buf = NULL;
23.1005 + nuv_frame_header h;
23.1006 +
23.1007 + res = gst_nuv_demux_frame_header_load (nuv, &h);
23.1008 + if (res != GST_FLOW_OK)
23.1009 + return res;
23.1010 +
23.1011 + if (h.i_length != 512) {
23.1012 + return GST_FLOW_ERROR;
23.1013 + }
23.1014 + nuv->priv->state = GST_NUV_DEMUX_EXTEND_HEADER_DATA;
23.1015 + } else {
23.1016 + nuv->priv->state = GST_NUV_DEMUX_INVALID_DATA;
23.1017 + g_object_unref (buf);
23.1018 + GST_ELEMENT_WARNING (nuv, STREAM, FAILED,
23.1019 + (_("incomplete NUV support")), ("incomplete NUV support"));
23.1020 + return GST_FLOW_ERROR;
23.1021 + }
23.1022 + return res;
23.1023 +}
23.1024 +
23.1025 +static void
23.1026 +gst_nuv_demux_create_seek_index (GstNuvDemux * nuv)
23.1027 +{
23.1028 + GstMessage *msg;
23.1029 + nuv_frame_header h;
23.1030 +
23.1031 + while (gst_nuv_demux_frame_header_load (nuv, &h) == GST_FLOW_OK) {
23.1032 + if ((h.i_type == 'V') && (h.i_keyframe == 0)) {
23.1033 + frame_index_data *f = g_new0 (frame_index_data, 1);
23.1034 +
23.1035 + f->offset = nuv->priv->offset - 12;
23.1036 + f->timecode = h.i_timecode * GST_MSECOND;
23.1037 +
23.1038 + nuv->priv->index = g_slist_append (nuv->priv->index, f);
23.1039 + }
23.1040 + if (h.i_type != 'R') {
23.1041 + nuv->priv->offset += h.i_length;
23.1042 + if (h.i_type == 'A' || h.i_type == 'V')
23.1043 + nuv->priv->duration_time = h.i_timecode * GST_MSECOND;
23.1044 + }
23.1045 + }
23.1046 + GST_DEBUG_OBJECT (nuv, "CREATING INDEX: DONE : DURATION Bytes/Sec: %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT,
23.1047 + nuv->priv->offset, nuv->priv->duration_time);
23.1048 +
23.1049 + nuv->priv->duration_bytes = nuv->priv->offset;
23.1050 + nuv->priv->offset = nuv->priv->header_lengh;
23.1051 +
23.1052 + msg = gst_message_new_duration (GST_OBJECT (nuv), GST_FORMAT_TIME, nuv->priv->duration_time);
23.1053 + gst_element_post_message (GST_ELEMENT (nuv), msg);
23.1054 +}
23.1055 +
23.1056 +static GstFlowReturn
23.1057 +gst_nuv_demux_play (GstPad * pad)
23.1058 +{
23.1059 + GstFlowReturn res = GST_FLOW_OK;
23.1060 + GstNuvDemux *nuv = GST_NUV_DEMUX (GST_PAD_PARENT (pad));
23.1061 +
23.1062 + switch (nuv->priv->state) {
23.1063 + case GST_NUV_DEMUX_START:
23.1064 + res = gst_nuv_demux_stream_file_header (nuv);
23.1065 + if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
23.1066 + goto pause;
23.1067 + }
23.1068 + break;
23.1069 +
23.1070 + case GST_NUV_DEMUX_HEADER_DATA:
23.1071 + res = gst_nuv_demux_stream_header_data (nuv);
23.1072 + if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
23.1073 + goto pause;
23.1074 + }
23.1075 + break;
23.1076 +
23.1077 + case GST_NUV_DEMUX_EXTRA_DATA:
23.1078 + res = gst_nuv_demux_stream_extra_data (nuv);
23.1079 + if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
23.1080 + goto pause;
23.1081 + }
23.1082 + break;
23.1083 +
23.1084 + case GST_NUV_DEMUX_MPEG_DATA:
23.1085 + res = gst_nuv_demux_stream_mpeg_data (nuv);
23.1086 + if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
23.1087 + goto pause;
23.1088 + }
23.1089 + break;
23.1090 +
23.1091 + case GST_NUV_DEMUX_EXTEND_HEADER:
23.1092 + res = gst_nuv_demux_stream_extend_header (nuv);
23.1093 + if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
23.1094 + goto pause;
23.1095 + }
23.1096 + break;
23.1097 +
23.1098 + case GST_NUV_DEMUX_EXTEND_HEADER_DATA:
23.1099 + res = gst_nuv_demux_stream_extend_header_data (nuv);
23.1100 + if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
23.1101 + goto pause;
23.1102 + }
23.1103 + //store file header size
23.1104 + nuv->priv->header_lengh = nuv->priv->offset;
23.1105 + break;
23.1106 +
23.1107 + case GST_NUV_DEMUX_INDEX_CREATE:
23.1108 + if (nuv->priv->mode == NUV_PULL_MODE) {
23.1109 + gst_nuv_demux_create_seek_index (nuv);
23.1110 + }
23.1111 +
23.1112 + case GST_NUV_DEMUX_FRAME_HEADER:
23.1113 + res = gst_nuv_demux_read_head_frame (nuv);
23.1114 + if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
23.1115 + goto pause;
23.1116 + }
23.1117 + break;
23.1118 +
23.1119 + case GST_NUV_DEMUX_MOVI:
23.1120 + res = gst_nuv_demux_stream_data (nuv);
23.1121 + if ((res != GST_FLOW_OK) && (res != GST_FLOW_ERROR_NO_DATA)) {
23.1122 + goto pause;
23.1123 + }
23.1124 + break;
23.1125 +
23.1126 + case GST_NUV_DEMUX_INVALID_DATA:
23.1127 + goto pause;
23.1128 + break;
23.1129 + default:
23.1130 + g_assert_not_reached ();
23.1131 + }
23.1132 +
23.1133 + return GST_FLOW_OK;
23.1134 +
23.1135 +pause:
23.1136 + GST_LOG_OBJECT (nuv, "pausing task, reason %s", gst_flow_get_name (res));
23.1137 + gst_pad_pause_task (nuv->priv->sinkpad);
23.1138 +
23.1139 + if (res == GST_FLOW_ERROR_EOS) {
23.1140 + gst_nuv_demux_send_eos (nuv);
23.1141 + nuv->priv->eos = TRUE;
23.1142 + res = GST_FLOW_OK;
23.1143 + }
23.1144 +
23.1145 + if (GST_FLOW_IS_FATAL (res)) {
23.1146 + GST_ELEMENT_ERROR (nuv, STREAM, FAILED,
23.1147 + (_("Internal data stream error.")),
23.1148 + ("streaming stopped, reason %s", gst_flow_get_name (res)));
23.1149 +
23.1150 + gst_nuv_demux_send_eos (nuv);
23.1151 + }
23.1152 + return res;
23.1153 +}
23.1154 +
23.1155 +static void
23.1156 +gst_nuv_demux_send_eos (GstNuvDemux * nuv)
23.1157 +{
23.1158 + gst_element_post_message (GST_ELEMENT (nuv),
23.1159 + gst_message_new_segment_done (GST_OBJECT (nuv), GST_FORMAT_TIME, -1));
23.1160 +
23.1161 + if (nuv->priv->src_video_pad)
23.1162 + gst_pad_push_event (nuv->priv->src_video_pad, gst_event_new_eos ());
23.1163 + if (nuv->priv->src_audio_pad)
23.1164 + gst_pad_push_event (nuv->priv->src_audio_pad, gst_event_new_eos ());
23.1165 +}
23.1166 +
23.1167 +static GstFlowReturn
23.1168 +gst_nuv_demux_read_bytes (GstNuvDemux * nuv, guint64 size, gboolean move,
23.1169 + GstBuffer ** buffer)
23.1170 +{
23.1171 + GstFlowReturn ret = GST_FLOW_OK;
23.1172 +
23.1173 + if (size == 0) {
23.1174 + return ret;
23.1175 + }
23.1176 +
23.1177 +
23.1178 + if (nuv->priv->mode == NUV_PULL_MODE) {
23.1179 + ret = gst_pad_pull_range (nuv->priv->sinkpad, nuv->priv->offset, size, buffer);
23.1180 + if (ret == GST_FLOW_OK) {
23.1181 + if (move) {
23.1182 + nuv->priv->offset += size;
23.1183 + }
23.1184 + /* got eos */
23.1185 + } else if (ret == GST_FLOW_UNEXPECTED) {
23.1186 + return GST_FLOW_ERROR_EOS;
23.1187 + }
23.1188 + } else {
23.1189 + if (gst_adapter_available (nuv->priv->adapter) < size) {
23.1190 + nuv->priv->more_data = TRUE;
23.1191 + return GST_FLOW_ERROR_NO_DATA;
23.1192 + }
23.1193 + if (move) {
23.1194 + *buffer = gst_adapter_take_buffer (nuv->priv->adapter, size);
23.1195 + } else {
23.1196 + guint8 *data = NULL;
23.1197 + data = (guint8 *) gst_adapter_peek (nuv->priv->adapter, size);
23.1198 + *buffer = gst_buffer_new ();
23.1199 + gst_buffer_set_data (*buffer, data, size);
23.1200 + }
23.1201 + }
23.1202 + return ret;
23.1203 +}
23.1204 +
23.1205 +static gboolean
23.1206 +gst_nuv_demux_sink_activate (GstPad * sinkpad)
23.1207 +{
23.1208 + gboolean res = TRUE;
23.1209 + GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (sinkpad));
23.1210 +
23.1211 + if (gst_pad_check_pull_range (sinkpad)) {
23.1212 + gst_adapter_clear (nuv->priv->adapter);
23.1213 + res = gst_pad_activate_pull (sinkpad, TRUE);
23.1214 + } else {
23.1215 + gst_adapter_clear (nuv->priv->adapter);
23.1216 + res = gst_pad_activate_push (sinkpad, TRUE);
23.1217 + }
23.1218 +
23.1219 + g_object_unref (nuv);
23.1220 + return res;
23.1221 +}
23.1222 +
23.1223 +static gboolean
23.1224 +gst_nuv_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
23.1225 +{
23.1226 + GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (sinkpad));
23.1227 +
23.1228 + if (active) {
23.1229 + GST_DEBUG_OBJECT (nuv, "activating pull function");
23.1230 + nuv->priv->mode = NUV_PULL_MODE;
23.1231 + gst_adapter_clear (nuv->priv->adapter);
23.1232 +
23.1233 + gst_pad_start_task (sinkpad, (GstTaskFunction) gst_nuv_demux_loop, sinkpad);
23.1234 + } else {
23.1235 + GST_DEBUG_OBJECT (nuv, "deactivating pull function");
23.1236 + gst_pad_stop_task (sinkpad);
23.1237 + }
23.1238 + gst_object_unref (nuv);
23.1239 +
23.1240 + return TRUE;
23.1241 +}
23.1242 +
23.1243 +static gboolean
23.1244 +gst_nuv_demux_sink_activate_push (GstPad * pad, gboolean active)
23.1245 +{
23.1246 + GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (pad));
23.1247 +
23.1248 + if (active) {
23.1249 + nuv->priv->mode = NUV_PUSH_MODE;
23.1250 + gst_adapter_clear (nuv->priv->adapter);
23.1251 +
23.1252 + GST_DEBUG_OBJECT (nuv, "activating push/chain function");
23.1253 + } else {
23.1254 + GST_DEBUG_OBJECT (nuv, "deactivating push/chain function");
23.1255 + }
23.1256 +
23.1257 + gst_object_unref (nuv);
23.1258 +
23.1259 + return TRUE;
23.1260 +}
23.1261 +
23.1262 +static frame_index_data *
23.1263 +gst_nuv_demux_do_seek_index (GstNuvDemux *nuv, gint64 seek_pos,
23.1264 + gint64 segment_stop, GstFormat format)
23.1265 +{
23.1266 + GSList *l;
23.1267 + frame_index_data *ret = NULL;
23.1268 +
23.1269 + if (nuv->priv->index == NULL) {
23.1270 + return NULL;
23.1271 + }
23.1272 +
23.1273 + /* find keyframe closest to the requested position */
23.1274 + for (l = nuv->priv->index; l != NULL; l = l->next) {
23.1275 + frame_index_data *f = (frame_index_data *) l->data;
23.1276 + gint64 pos = 0;
23.1277 +
23.1278 + if (format == GST_FORMAT_BYTES) {
23.1279 + pos = f->offset;
23.1280 + } else if (format == GST_FORMAT_TIME) {
23.1281 + pos = f->timecode;
23.1282 + } else {
23.1283 + return NULL;
23.1284 + }
23.1285 +
23.1286 + if (pos >= seek_pos) {
23.1287 + ret = f;
23.1288 + break;
23.1289 + }
23.1290 +
23.1291 + if ((segment_stop != -1) && (segment_stop != GST_CLOCK_TIME_NONE) && (pos > segment_stop)) {
23.1292 + break;
23.1293 + }
23.1294 + }
23.1295 +
23.1296 + return ret;
23.1297 +}
23.1298 +
23.1299 +static gboolean
23.1300 +gst_nuv_demux_do_seek (GstNuvDemux *nuv, GstEvent * event)
23.1301 +{
23.1302 + gdouble rate;
23.1303 + GstFormat format;
23.1304 + GstSeekFlags flags;
23.1305 + GstSeekType cur_type;
23.1306 + gint64 cur;
23.1307 + GstSeekType stop_type;
23.1308 + gint64 stop;
23.1309 + gboolean flush;
23.1310 + frame_index_data *entry;
23.1311 + gint64 segment_start;
23.1312 + gint64 segment_stop;
23.1313 + GstEvent *newsegment_event;
23.1314 +
23.1315 + if (nuv->priv->eos) {
23.1316 + return FALSE;
23.1317 + }
23.1318 +
23.1319 + if (nuv->priv->mode == NUV_PUSH_MODE) {
23.1320 + return FALSE;
23.1321 + }
23.1322 +
23.1323 +
23.1324 + gst_event_parse_seek (event, &rate, &format, &flags,
23.1325 + &cur_type, &cur, &stop_type, &stop);
23.1326 +
23.1327 +
23.1328 +
23.1329 +/*
23.1330 + if (format == GST_FORMAT_TIME) {
23.1331 + GST_DEBUG_OBJECT (nuv, "Can only seek on BYTES");
23.1332 + return FALSE;
23.1333 + }
23.1334 +*/
23.1335 +
23.1336 + if (rate <= 0.0) {
23.1337 + GST_DEBUG_OBJECT (nuv, "Can only seek with positive rate");
23.1338 + return FALSE;
23.1339 + }
23.1340 +
23.1341 + if (cur_type == GST_SEEK_TYPE_SET) {
23.1342 + GST_OBJECT_LOCK (nuv);
23.1343 + if (gst_nuv_demux_do_seek_index (nuv, cur, -1, format) == NULL) {
23.1344 + GST_DEBUG_OBJECT (nuv, "No matching seek entry in index");
23.1345 + GST_OBJECT_UNLOCK (nuv);
23.1346 + return FALSE;
23.1347 + }
23.1348 + GST_OBJECT_UNLOCK (nuv);
23.1349 + }
23.1350 +
23.1351 + flush = !!(flags & GST_SEEK_FLAG_FLUSH);
23.1352 +
23.1353 + if (flush) {
23.1354 + gst_pad_push_event (nuv->priv->sinkpad, gst_event_new_flush_start ());
23.1355 + if (nuv->priv->src_video_pad != NULL) {
23.1356 + gst_pad_push_event (nuv->priv->src_video_pad, gst_event_new_flush_start ());
23.1357 + }
23.1358 +
23.1359 + if (nuv->priv->src_audio_pad != NULL) {
23.1360 + gst_pad_push_event (nuv->priv->src_audio_pad, gst_event_new_flush_start ());
23.1361 + }
23.1362 + }
23.1363 + else {
23.1364 + gst_pad_pause_task (nuv->priv->sinkpad);
23.1365 + }
23.1366 +
23.1367 + GST_PAD_STREAM_LOCK (nuv->priv->sinkpad);
23.1368 + GST_OBJECT_LOCK (nuv);
23.1369 +
23.1370 +
23.1371 + if (cur == GST_CLOCK_TIME_NONE)
23.1372 + cur = 0;
23.1373 + if (stop == GST_CLOCK_TIME_NONE)
23.1374 + stop = nuv->priv->duration_time;
23.1375 +
23.1376 + if (cur_type == GST_SEEK_TYPE_SET)
23.1377 + segment_start = cur;
23.1378 + else if (cur_type == GST_SEEK_TYPE_CUR)
23.1379 + segment_start = nuv->priv->segment_start + cur;
23.1380 + else
23.1381 + segment_start = nuv->priv->segment_start;
23.1382 +
23.1383 + if (stop_type == GST_SEEK_TYPE_SET)
23.1384 + segment_stop = stop;
23.1385 + else if (stop_type == GST_SEEK_TYPE_CUR)
23.1386 + segment_stop = nuv->priv->segment_stop + stop;
23.1387 + else
23.1388 + segment_stop = nuv->priv->segment_stop;
23.1389 +
23.1390 + segment_start = CLAMP (segment_start, 0, nuv->priv->duration_time);
23.1391 + segment_stop = CLAMP (segment_stop, 0, nuv->priv->duration_time);
23.1392 +
23.1393 + entry = gst_nuv_demux_do_seek_index (nuv, segment_start,
23.1394 + segment_stop, format);
23.1395 +
23.1396 + if (entry == NULL) {
23.1397 + GST_DEBUG_OBJECT (nuv, "No matching seek entry in index");
23.1398 + goto seek_error;
23.1399 + }
23.1400 +
23.1401 + segment_start = entry->timecode;
23.1402 +
23.1403 + nuv->priv->segment_start = segment_start;
23.1404 + nuv->priv->segment_stop = segment_stop;
23.1405 +
23.1406 + GST_OBJECT_UNLOCK (nuv);
23.1407 +
23.1408 + if (!nuv->priv->eos) {
23.1409 + GstMessage *msg;
23.1410 + msg = gst_message_new_segment_start (GST_OBJECT (nuv), GST_FORMAT_TIME,
23.1411 + nuv->priv->segment_start);
23.1412 +
23.1413 + gst_element_post_message (GST_ELEMENT (nuv), msg);
23.1414 + }
23.1415 +
23.1416 + GST_DEBUG_OBJECT (nuv, "NEW SEGMENT START %" G_GUINT64_FORMAT ", STOP %" G_GUINT64_FORMAT,
23.1417 + segment_start, segment_stop);
23.1418 + newsegment_event = gst_event_new_new_segment (FALSE, rate,
23.1419 + GST_FORMAT_TIME, segment_start, segment_stop, segment_start);
23.1420 +
23.1421 +
23.1422 + if (flush) {
23.1423 + if (nuv->priv->src_video_pad != NULL) {
23.1424 + gst_pad_push_event (nuv->priv->src_video_pad, gst_event_new_flush_stop ());
23.1425 + }
23.1426 +
23.1427 + if (nuv->priv->src_audio_pad != NULL) {
23.1428 + gst_pad_push_event (nuv->priv->src_audio_pad, gst_event_new_flush_stop ());
23.1429 + }
23.1430 +
23.1431 + gst_pad_push_event (nuv->priv->sinkpad, gst_event_new_flush_stop ());
23.1432 + }
23.1433 +
23.1434 +
23.1435 + if (nuv->priv->src_video_pad != NULL) {
23.1436 + gst_pad_push_event (nuv->priv->src_video_pad, gst_event_ref (newsegment_event));
23.1437 + }
23.1438 + if (nuv->priv->src_audio_pad != NULL) {
23.1439 + gst_pad_push_event (nuv->priv->src_audio_pad, gst_event_ref (newsegment_event));
23.1440 + }
23.1441 +
23.1442 + gst_event_unref (newsegment_event);
23.1443 +
23.1444 + nuv->priv->state = GST_NUV_DEMUX_FRAME_HEADER;
23.1445 + nuv->priv->offset = entry->offset;
23.1446 +
23.1447 + gst_pad_start_task (nuv->priv->sinkpad, (GstTaskFunction) gst_nuv_demux_loop,
23.1448 + nuv->priv->sinkpad);
23.1449 +
23.1450 + GST_PAD_STREAM_UNLOCK (nuv->priv->sinkpad);
23.1451 + return TRUE;
23.1452 +
23.1453 +seek_error:
23.1454 + GST_DEBUG_OBJECT (nuv, "Got a seek error");
23.1455 + GST_OBJECT_UNLOCK (nuv);
23.1456 + GST_PAD_STREAM_UNLOCK (nuv->priv->sinkpad);
23.1457 + return FALSE;
23.1458 +
23.1459 +}
23.1460 +
23.1461 +static gboolean
23.1462 +gst_nuv_demux_srcpad_event (GstPad * pad, GstEvent * event)
23.1463 +{
23.1464 + gboolean res = FALSE;
23.1465 + GstNuvDemux *nuv;
23.1466 +
23.1467 + nuv = GST_NUV_DEMUX (gst_pad_get_parent (pad));
23.1468 +
23.1469 + switch (GST_EVENT_TYPE (event)) {
23.1470 + case GST_EVENT_SEEK:
23.1471 + res = gst_nuv_demux_do_seek (nuv, event);
23.1472 + break;
23.1473 + default:
23.1474 + res = FALSE;
23.1475 + break;
23.1476 + }
23.1477 +
23.1478 + gst_object_unref (nuv);
23.1479 + return res;
23.1480 +}
23.1481 +
23.1482 +static GstFlowReturn
23.1483 +gst_nuv_demux_chain (GstPad * pad, GstBuffer * buf)
23.1484 +{
23.1485 + GstFlowReturn ret = GST_FLOW_OK;
23.1486 + GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (pad));
23.1487 +
23.1488 + if (nuv->priv->mode != NUV_PUSH_MODE)
23.1489 + return ret;
23.1490 +
23.1491 + gst_adapter_push (nuv->priv->adapter, buf);
23.1492 +
23.1493 + while ((ret == GST_FLOW_OK) && (nuv->priv->more_data == FALSE)) {
23.1494 + ret = gst_nuv_demux_play (pad);
23.1495 + }
23.1496 +
23.1497 + nuv->priv->more_data = FALSE;
23.1498 + gst_object_unref (nuv);
23.1499 +
23.1500 + return ret;
23.1501 +}
23.1502 +
23.1503 +static void
23.1504 +gst_nuv_demux_loop (GstPad * pad)
23.1505 +{
23.1506 + gst_nuv_demux_play (pad);
23.1507 +}
23.1508 +
23.1509 +static void
23.1510 +gst_nuv_demux_index_free (gpointer data, gpointer user_data)
23.1511 +{
23.1512 + g_free (data);
23.1513 +}
23.1514 +
23.1515 +static void
23.1516 +gst_nuv_demux_reset (GstNuvDemux * nuv)
23.1517 +{
23.1518 + nuv->priv->eos = FALSE;
23.1519 + nuv->priv->more_data = FALSE;
23.1520 + nuv->priv->state = GST_NUV_DEMUX_START;
23.1521 + nuv->priv->mode = NUV_PUSH_MODE;
23.1522 + nuv->priv->offset = 0;
23.1523 + nuv->priv->time_start = 0;
23.1524 + nuv->priv->time_qos = GST_CLOCK_TIME_NONE;
23.1525 + nuv->priv->duration_bytes = GST_CLOCK_TIME_NONE;
23.1526 + nuv->priv->duration_time = GST_CLOCK_TIME_NONE;
23.1527 + nuv->priv->last_video_return = GST_FLOW_OK;
23.1528 + nuv->priv->last_audio_return = GST_FLOW_OK;
23.1529 + nuv->priv->header_lengh = 0;
23.1530 + nuv->priv->segment_stop = GST_CLOCK_TIME_NONE;
23.1531 + nuv->priv->segment_start = GST_CLOCK_TIME_NONE;
23.1532 +
23.1533 + //clear index list
23.1534 + g_slist_foreach (nuv->priv->index, gst_nuv_demux_index_free, NULL);
23.1535 + g_slist_free (nuv->priv->index);
23.1536 + nuv->priv->index = NULL;
23.1537 +
23.1538 + gst_adapter_clear (nuv->priv->adapter);
23.1539 +
23.1540 + if (nuv->priv->mpeg_buffer != NULL) {
23.1541 + gst_buffer_unref (nuv->priv->mpeg_buffer);
23.1542 + nuv->priv->mpeg_buffer = NULL;
23.1543 + }
23.1544 +}
23.1545 +
23.1546 +static void
23.1547 +gst_nuv_demux_destoy_src_pad (GstNuvDemux * nuv)
23.1548 +{
23.1549 + if (nuv->priv->src_video_pad) {
23.1550 + gst_element_remove_pad (GST_ELEMENT (nuv), nuv->priv->src_video_pad);
23.1551 + nuv->priv->src_video_pad = NULL;
23.1552 + }
23.1553 +
23.1554 + if (nuv->priv->src_audio_pad) {
23.1555 + gst_element_remove_pad (GST_ELEMENT (nuv), nuv->priv->src_audio_pad);
23.1556 + nuv->priv->src_audio_pad = NULL;
23.1557 + }
23.1558 +}
23.1559 +
23.1560 +static GstStateChangeReturn
23.1561 +gst_nuv_demux_change_state (GstElement * element, GstStateChange transition)
23.1562 +{
23.1563 + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
23.1564 +
23.1565 + switch (transition) {
23.1566 + case GST_STATE_CHANGE_NULL_TO_READY:
23.1567 + gst_nuv_demux_reset (GST_NUV_DEMUX (element));
23.1568 + gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (element));
23.1569 + break;
23.1570 + default:
23.1571 + break;
23.1572 + }
23.1573 +
23.1574 + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
23.1575 + if (ret == GST_STATE_CHANGE_FAILURE) {
23.1576 + goto done;
23.1577 + }
23.1578 +
23.1579 + switch (transition) {
23.1580 + case GST_STATE_CHANGE_READY_TO_NULL:
23.1581 + gst_nuv_demux_reset (GST_NUV_DEMUX (element));
23.1582 + gst_nuv_demux_destoy_src_pad (GST_NUV_DEMUX (element));
23.1583 + break;
23.1584 + default:
23.1585 + break;
23.1586 + }
23.1587 +
23.1588 +done:
23.1589 + return ret;
23.1590 +}
23.1591 +
23.1592 +#if (GST_VERSION_MINOR == 10) && (GST_VERSION_MICRO < 6)
23.1593 +GstBuffer *
23.1594 +gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
23.1595 +{
23.1596 + GstBuffer *buffer;
23.1597 + GstBuffer *cur;
23.1598 + guint8 *data;
23.1599 +
23.1600 + g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
23.1601 + g_return_val_if_fail (nbytes > 0, NULL);
23.1602 +
23.1603 + GST_LOG_OBJECT (adapter, "taking buffer of %u bytes", nbytes);
23.1604 +
23.1605 + /* we don't have enough data, return NULL. This is unlikely
23.1606 + * as one usually does an _available() first instead of peeking a
23.1607 + * random size. */
23.1608 + if (G_UNLIKELY (nbytes > adapter->size))
23.1609 + return NULL;
23.1610 +
23.1611 + /* our head buffer has enough data left, return it */
23.1612 + cur = adapter->buflist->data;
23.1613 + if (GST_BUFFER_SIZE (cur) >= nbytes + adapter->skip) {
23.1614 + GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer",
23.1615 + nbytes);
23.1616 + buffer = gst_buffer_create_sub (cur, adapter->skip, nbytes);
23.1617 +
23.1618 + gst_adapter_flush (adapter, nbytes);
23.1619 +
23.1620 + return buffer;
23.1621 + }
23.1622 +
23.1623 + data = gst_adapter_take (adapter, nbytes);
23.1624 + if (data == NULL)
23.1625 + return NULL;
23.1626 +
23.1627 + buffer = gst_buffer_new ();
23.1628 + GST_BUFFER_DATA (buffer) = data;
23.1629 + GST_BUFFER_MALLOCDATA (buffer) = data;
23.1630 + GST_BUFFER_SIZE (buffer) = nbytes;
23.1631 +
23.1632 + return buffer;
23.1633 +}
23.1634 +#endif
23.1635 +
23.1636 +static void
23.1637 +gst_nuv_typefind (GstTypeFind * tf, gpointer unused)
23.1638 +{
23.1639 + guint8 *data = gst_type_find_peek (tf, 0, 11);
23.1640 +
23.1641 + if (data) {
23.1642 + if (memcmp (data, "MythTVVideo", 11) == 0
23.1643 + || memcmp (data, "NuppelVideo", 11) == 0) {
23.1644 + gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM,
23.1645 + gst_caps_new_simple ("video/x-nuv", NULL));
23.1646 + }
23.1647 + }
23.1648 +}
23.1649 +
23.1650 +static gboolean
23.1651 +plugin_init (GstPlugin * plugin)
23.1652 +{
23.1653 + static gchar *exts[] = { "nuv", NULL };
23.1654 +#ifdef ENABLE_NLS
23.1655 + setlocale (LC_ALL, "");
23.1656 + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
23.1657 +#endif /* ENABLE_NLS */
23.1658 +
23.1659 + if (!gst_element_register (plugin, "nuvdemux", GST_RANK_SECONDARY,
23.1660 + GST_TYPE_NUV_DEMUX)) {
23.1661 + return FALSE;
23.1662 + }
23.1663 +
23.1664 + if (!gst_type_find_register (plugin, "video/x-nuv", GST_RANK_SECONDARY,
23.1665 + gst_nuv_typefind,
23.1666 + exts,
23.1667 + gst_caps_new_simple ("video/x-nuv", NULL), NULL, NULL)) {
23.1668 + GST_WARNING ("can't register typefind");
23.1669 + return FALSE;
23.1670 + }
23.1671 +
23.1672 + return TRUE;
23.1673 +}
23.1674 +
23.1675 +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
23.1676 + GST_VERSION_MINOR,
23.1677 + "nuvdemux",
23.1678 + "Demuxes and muxes audio and video",
23.1679 + plugin_init, VERSION, "LGPL", "NuvDemux", "")
23.1680 +
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/gst-gmyth/nuvdemux/gstnuvdemux.h Tue May 01 16:04:02 2007 +0100
24.3 @@ -0,0 +1,55 @@
24.4 +/* GStreamer
24.5 + * Copyright (C) <2006> Renato Araujo Oliveira Filho <renato.filho@indt.org.br>
24.6 + * Rosfran Borges <rosfran.borges@indt.org.br>
24.7 + *
24.8 + * This library is free software; you can redistribute it and/or
24.9 + * modify it under the terms of the GNU Library General Public
24.10 + * License as published by the Free Software Foundation; either
24.11 + * version 2 of the License, or (at your option) any later version.
24.12 + *
24.13 + * This library is distributed in the hope that it will be useful,
24.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24.16 + * Library General Public License for more details.
24.17 + *
24.18 + * You should have received a copy of the GNU Library General Public
24.19 + * License along with this library; if not, write to the
24.20 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24.21 + * Boston, MA 02111-1307, USA.
24.22 + */
24.23 +
24.24 +#ifndef __GST_NUV_DEMUX_H__
24.25 +#define __GST_NUV_DEMUX_H__
24.26 +
24.27 +#include <gst/gst.h>
24.28 +
24.29 +#include <gst/base/gstadapter.h>
24.30 +
24.31 +G_BEGIN_DECLS
24.32 +
24.33 +#define GST_TYPE_NUV_DEMUX \
24.34 + (gst_nuv_demux_get_type ())
24.35 +#define GST_NUV_DEMUX(obj) \
24.36 + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_NUV_DEMUX, GstNuvDemux))
24.37 +#define GST_NUV_DEMUX_CLASS(klass) \
24.38 + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_NUV_DEMUX, GstNuvDemuxClass))
24.39 +#define GST_IS_NUV_DEMUX(obj) \
24.40 + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_NUV_DEMUX))
24.41 +#define GST_IS_NUV_DEMUX_CLASS(klass) \
24.42 + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_NUV_DEMUX))
24.43 +
24.44 +typedef struct _GstNuvDemuxPrivate GstNuvDemuxPrivate;
24.45 +typedef struct _GstNuvDemux {
24.46 + GstElement parent;
24.47 + GstNuvDemuxPrivate *priv;
24.48 +} GstNuvDemux;
24.49 +
24.50 +typedef struct _GstNuvDemuxClass {
24.51 + GstElementClass parent_class;
24.52 +} GstNuvDemuxClass;
24.53 +
24.54 +GType gst_nuv_demux_get_type (void);
24.55 +
24.56 +G_END_DECLS
24.57 +
24.58 +#endif /* __GST_NUV_DEMUX_H__ */