+++ /dev/null
-Visa Smolander <visa.smolander@nokia.com>
-Zeeshan Ali <zeeshan.ali@nokia.com>
-Mikael Saarenpää <mikael.saarenpaa@nokia.com>
-Antía Puentes Felpeto <apuentes@igalia.com>
-Iago Toral Quiroga <itoral@igalia.com>
-Juan Suárez Romero <jasuarez@igalia.com>
-Sandor Pinter <sandor.pinter@blumsoft.eu>
-Xabier Rodríguez Calvar <xrcalvar@igalia.com>
-Juha Kellokoski <veitikka6@gmail.com>
-Mika Tapojarvi <mika.tapojarvi@sse.fi>
+++ /dev/null
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-\f
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-\f
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-\f
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-\f
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-\f
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
+++ /dev/null
-#
-# Makefile.am for MAFW gst renderer library.
-#
-# Author: Visa Smolander <visa.smolander@nokia.com>
-#
-# Copyright (C) 2007, 2008, 2009 Nokia. All rights reserved.
-
-
-SUBDIRS = libmafw-gst-renderer applet po
-
-if ENABLE_TESTS
-SUBDIRS += tests
-endif
-
-noinst_DATA = mafw-gst-renderer-uninstalled.pc
-EXTRA_DIST = mafw-gst-renderer-uninstalled.pc.in
-
-# Extra clean files so that maintainer-clean removes *everything*
-MAINTAINERCLEANFILES = aclocal.m4 compile config.guess \
- config.sub configure depcomp \
- install-sh ltmain.sh Makefile.in \
- missing config.h.in *-stamp omf.make
-
-if ENABLE_COVERAGE
-LCOV_DATA_DIR = lcov-data
-LCOV_DATA_FILE = lcov.info
-
-distclean-local:
- -rm -rf $(LCOV_DATA_DIR)
-
-lcov-zero-counters:
- $(LCOV) -z -d .
-
-lcov:
- -mkdir -p $(LCOV_DATA_DIR)
- $(LCOV) -c -d . -o $(LCOV_DATA_DIR)/$(LCOV_DATA_FILE)
- genhtml -s $(LCOV_DATA_DIR)/$(LCOV_DATA_FILE) -o $(LCOV_DATA_DIR)
- @echo
- @echo "Please, have a look on ./$(LCOV_DATA_DIR)/index.html for coverage statistics"
- @echo
-endif
+++ /dev/null
-dnl AM_PATH_CHECK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
-dnl Test for check, and define CHECK_CFLAGS and CHECK_LIBS
-dnl
-
-AC_DEFUN([AM_PATH_CHECK],
-[
- AC_ARG_WITH(check,
- [ --with-check=PATH prefix where check is installed [default=auto]])
-
- min_check_version=ifelse([$1], ,0.8.2,$1)
-
- AC_MSG_CHECKING(for check - version >= $min_check_version)
-
- if test x$with_check = xno; then
- AC_MSG_RESULT(disabled)
- ifelse([$3], , AC_MSG_ERROR([disabling check is not supported]), [$3])
- else
- if test "x$with_check" != x; then
- CHECK_CFLAGS="-I$with_check/include"
- CHECK_LIBS="-L$with_check/lib -lcheck"
- else
- CHECK_CFLAGS=""
- CHECK_LIBS="-lcheck"
- fi
-
- ac_save_CFLAGS="$CFLAGS"
- ac_save_LIBS="$LIBS"
-
- CFLAGS="$CFLAGS $CHECK_CFLAGS"
- LIBS="$CHECK_LIBS $LIBS"
-
- rm -f conf.check-test
- AC_TRY_RUN([
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <check.h>
-
-int main ()
-{
- int major, minor, micro;
- char *tmp_version;
-
- system ("touch conf.check-test");
-
- /* HP/UX 9 (%@#!) writes to sscanf strings */
- tmp_version = strdup("$min_check_version");
- if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
- printf("%s, bad version string\n", "$min_check_version");
- return 1;
- }
-
- if ((CHECK_MAJOR_VERSION != check_major_version) ||
- (CHECK_MINOR_VERSION != check_minor_version) ||
- (CHECK_MICRO_VERSION != check_micro_version))
- {
- printf("\n*** The check header file (version %d.%d.%d) does not match\n",
- CHECK_MAJOR_VERSION, CHECK_MINOR_VERSION, CHECK_MICRO_VERSION);
- printf("*** the check library (version %d.%d.%d).\n",
- check_major_version, check_minor_version, check_micro_version);
- return 1;
- }
-
- if ((check_major_version > major) ||
- ((check_major_version == major) && (check_minor_version > minor)) ||
- ((check_major_version == major) && (check_minor_version == minor) && (check_micro_version >= micro)))
- {
- return 0;
- }
- else
- {
- printf("\n*** An old version of check (%d.%d.%d) was found.\n",
- check_major_version, check_minor_version, check_micro_version);
- printf("*** You need a version of check being at least %d.%d.%d.\n", major, minor, micro);
- printf("***\n");
- printf("*** If you have already installed a sufficiently new version, this error\n");
- printf("*** probably means that the wrong copy of the check library and header\n");
- printf("*** file is being found. Rerun configure with the --with-check=PATH option\n");
- printf("*** to specify the prefix where the correct version was installed.\n");
- }
-
- return 1;
-}
-],, no_check=yes, [echo $ac_n "cross compiling; assumed OK... $ac_c"])
-
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
-
- if test "x$no_check" = x ; then
- AC_MSG_RESULT(yes)
- ifelse([$2], , :, [$2])
- else
- AC_MSG_RESULT(no)
- if test -f conf.check-test ; then
- :
- else
- echo "*** Could not run check test program, checking why..."
- CFLAGS="$CFLAGS $CHECK_CFLAGS"
- LIBS="$CHECK_LIBS $LIBS"
- AC_TRY_LINK([
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <check.h>
-], , [ echo "*** The test program compiled, but did not run. This usually means"
- echo "*** that the run-time linker is not finding check. You'll need to set your"
- echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
- echo "*** to the installed location Also, make sure you have run ldconfig if that"
- echo "*** is required on your system"
- echo "***"
- echo "*** If you have an old version installed, it is best to remove it, although"
- echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
- [ echo "*** The test program failed to compile or link. See the file config.log for"
- echo "*** the exact error that occured." ])
-
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
- fi
-
- CHECK_CFLAGS=""
- CHECK_LIBS=""
-
- rm -f conf.check-test
- ifelse([$3], , AC_MSG_ERROR([check not found]), [$3])
- fi
-
- AC_SUBST(CHECK_CFLAGS)
- AC_SUBST(CHECK_LIBS)
-
- rm -f conf.check-test
-
- fi
-])
-
-dnl AM_MAFW_PLUGIN_CHECK(PLUGIN, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
-dnl Test to check whether a plugin exists
-dnl
-
-AC_DEFUN([AM_MAFW_PLUGIN_CHECK],
-[
- AC_MSG_CHECKING(for MAFW plugin)
-
- ac_save_CFLAGS="$CFLAGS"
- ac_save_LIBS="$LIBS"
- ac_save_CC="$CC"
-
- CFLAGS="$CFLAGS $(pkg-config mafw --cflags)"
- LIBS="$LIBS $(pkg-config mafw --libs)"
- CC="libtool --mode=link gcc"
-
- AC_TRY_RUN([
-#include <libmafw/mafw.h>
-
-int main ()
-{
- MafwRegistry *registry = NULL;
- gboolean result;
-
- g_type_init();
-
- registry = MAFW_REGISTRY(mafw_get_local_registry());
- if (!registry) {
- printf ("Cannot get registry\n");
- return 1;
- }
- result = mafw_local_registry_load_plugin(MAFW_LOCAL_REGISTRY(registry), $1, NULL);
- if (!result) {
- printf ("Unable to load %s\n", $1);
- return 1;
- } else {
- return 0;
- }
-}
- ], [$2], [$3])
-
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
- CC="$ac_save_CC"
-])
+++ /dev/null
-lib_LTLIBRARIES = libcpmpsubtitles.la
-
-libcpmpsubtitles_la_SOURCES = cpmpsubtitles.c
-libcpmpsubtitles_la_LIBADD = $(MAFW_SUBTITLES_CPA_LIBS)
-libcpmpsubtitles_la_CPPFLAGS = $(MAFW_SUBTITLES_CPA_CFLAGS)
-libcpmpsubtitles_la_LDFLAGS = module -avoid-version
-
-libdir = $(CPA_PLUGINDIR)
-
-desktop_DATA = cpmpsubtitles.desktop
-desktopdir = $(CPA_DESKTOPDIR)
-EXTRA_DIST = $(desktop_DATA)
+++ /dev/null
-/*
- * Subtitles control panel applet.
- * Copyright (C) 2010 Roman Moravcik
- *
- * encodings structure imported from totem-subtitle-encoding.c
- * Copyright (C) 2001-2006 Bastien Nocera <hadess@hadess.net>
- *
- * font family detection imported from hildon-font-selection-dialog.c
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-
-#include <gtk/gtk.h>
-#include <hildon/hildon.h>
-#include <hildon-cp-plugin/hildon-cp-plugin-interface.h>
-
-#include <gconf/gconf-client.h>
-
-#define GCONF_MAFW_GST_SUBTITLE_RENDERER "/system/mafw/mafw-gst-subtitles-renderer"
-#define _HL(str) dgettext("hildon-libs",str)
-
-typedef enum
-{
- FONT_STYLE_REGULAR,
- FONT_STYLE_ITALIC,
- FONT_STYLE_BOLD,
- FONT_STYLE_ITALIC_BOLD,
- FONT_STYLE_LAST,
-} FontStyleIndex;
-
-typedef struct {
- int index;
- const char *name;
-} FontStyle;
-
-static FontStyle font_styles[] = {
- {FONT_STYLE_REGULAR, N_("Regular")},
- {FONT_STYLE_ITALIC, N_("Italic")},
- {FONT_STYLE_BOLD, N_("Bold")},
- {FONT_STYLE_ITALIC_BOLD, N_("Italic Bold")}
-};
-
-static const gint font_sizes[] =
-{
- 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, -1
-};
-
-typedef enum
-{
- SUBTITLE_ENCODING_ISO_8859_6,
- SUBTITLE_ENCODING_IBM_864,
- SUBTITLE_ENCODING_MAC_ARABIC,
- SUBTITLE_ENCODING_WINDOWS_1256,
-
- SUBTITLE_ENCODING_ARMSCII_8,
-
- SUBTITLE_ENCODING_ISO_8859_4,
- SUBTITLE_ENCODING_ISO_8859_13,
- SUBTITLE_ENCODING_WINDOWS_1257,
-
- SUBTITLE_ENCODING_ISO_8859_14,
-
- SUBTITLE_ENCODING_ISO_8859_2,
- SUBTITLE_ENCODING_IBM_852,
- SUBTITLE_ENCODING_MAC_CE,
- SUBTITLE_ENCODING_WINDOWS_1250,
-
- SUBTITLE_ENCODING_GB18030,
- SUBTITLE_ENCODING_GB2312,
- SUBTITLE_ENCODING_GBK,
- SUBTITLE_ENCODING_HZ,
-
- SUBTITLE_ENCODING_BIG5,
- SUBTITLE_ENCODING_BIG5_HKSCS,
- SUBTITLE_ENCODING_EUC_TW,
-
- SUBTITLE_ENCODING_MAC_CROATIAN,
-
- SUBTITLE_ENCODING_ISO_8859_5,
- SUBTITLE_ENCODING_IBM_855,
- SUBTITLE_ENCODING_ISO_IR_111,
- SUBTITLE_ENCODING_KOI8_R,
- SUBTITLE_ENCODING_MAC_CYRILLIC,
- SUBTITLE_ENCODING_WINDOWS_1251,
-
- SUBTITLE_ENCODING_CP_866,
-
- SUBTITLE_ENCODING_MAC_UKRAINIAN,
- SUBTITLE_ENCODING_KOI8_U,
-
- SUBTITLE_ENCODING_GEOSTD8,
-
- SUBTITLE_ENCODING_ISO_8859_7,
- SUBTITLE_ENCODING_MAC_GREEK,
- SUBTITLE_ENCODING_WINDOWS_1253,
-
- SUBTITLE_ENCODING_MAC_GUJARATI,
-
- SUBTITLE_ENCODING_MAC_GURMUKHI,
-
- SUBTITLE_ENCODING_ISO_8859_8_I,
- SUBTITLE_ENCODING_IBM_862,
- SUBTITLE_ENCODING_MAC_HEBREW,
- SUBTITLE_ENCODING_WINDOWS_1255,
-
- SUBTITLE_ENCODING_ISO_8859_8,
-
- SUBTITLE_ENCODING_MAC_DEVANAGARI,
-
- SUBTITLE_ENCODING_MAC_ICELANDIC,
-
- SUBTITLE_ENCODING_EUC_JP,
- SUBTITLE_ENCODING_ISO_2022_JP,
- SUBTITLE_ENCODING_SHIFT_JIS,
-
- SUBTITLE_ENCODING_EUC_KR,
- SUBTITLE_ENCODING_ISO_2022_KR,
- SUBTITLE_ENCODING_JOHAB,
- SUBTITLE_ENCODING_UHC,
-
- SUBTITLE_ENCODING_ISO_8859_10,
-
- SUBTITLE_ENCODING_MAC_FARSI,
-
- SUBTITLE_ENCODING_ISO_8859_16,
- SUBTITLE_ENCODING_MAC_ROMANIAN,
-
- SUBTITLE_ENCODING_ISO_8859_3,
-
- SUBTITLE_ENCODING_TIS_620,
-
- SUBTITLE_ENCODING_ISO_8859_9,
- SUBTITLE_ENCODING_IBM_857,
- SUBTITLE_ENCODING_MAC_TURKISH,
- SUBTITLE_ENCODING_WINDOWS_1254,
-
- SUBTITLE_ENCODING_UTF_7,
- SUBTITLE_ENCODING_UTF_8,
- SUBTITLE_ENCODING_UTF_16,
- SUBTITLE_ENCODING_UCS_2,
- SUBTITLE_ENCODING_UCS_4,
-
- SUBTITLE_ENCODING_ISO_8859_1,
- SUBTITLE_ENCODING_ISO_8859_15,
- SUBTITLE_ENCODING_IBM_850,
- SUBTITLE_ENCODING_MAC_ROMAN,
- SUBTITLE_ENCODING_WINDOWS_1252,
-
- SUBTITLE_ENCODING_TCVN,
- SUBTITLE_ENCODING_VISCII,
- SUBTITLE_ENCODING_WINDOWS_1258,
-
- SUBTITLE_ENCODING_CURRENT_LOCALE,
-
- SUBTITLE_ENCODING_LAST
-} SubtitleEncodingIndex;
-
-typedef struct {
- int index;
- const char *charset;
- const char *name;
-} SubtitleEncoding;
-
-static SubtitleEncoding encodings[] = {
- {SUBTITLE_ENCODING_ISO_8859_6, "ISO-8859-6", N_("Arabic")},
- {SUBTITLE_ENCODING_IBM_864, "IBM864", N_("Arabic")},
- {SUBTITLE_ENCODING_MAC_ARABIC, "MAC_ARABIC", N_("Arabic")},
- {SUBTITLE_ENCODING_WINDOWS_1256, "WINDOWS-1256", N_("Arabic")},
-
- {SUBTITLE_ENCODING_ARMSCII_8, "ARMSCII-8", N_("Armenian")},
-
- {SUBTITLE_ENCODING_ISO_8859_4, "ISO-8859-4", N_("Baltic")},
- {SUBTITLE_ENCODING_ISO_8859_13, "ISO-8859-13", N_("Baltic")},
- {SUBTITLE_ENCODING_WINDOWS_1257, "WINDOWS-1257", N_("Baltic")},
-
- {SUBTITLE_ENCODING_ISO_8859_14, "ISO-8859-14", N_("Celtic")},
-
- {SUBTITLE_ENCODING_ISO_8859_2, "ISO-8859-2", N_("Central European")},
- {SUBTITLE_ENCODING_IBM_852, "IBM852", N_("Central European")},
- {SUBTITLE_ENCODING_MAC_CE, "MAC_CE", N_("Central European")},
- {SUBTITLE_ENCODING_WINDOWS_1250, "WINDOWS-1250", N_("Central European")},
-
- {SUBTITLE_ENCODING_GB18030, "GB18030", N_("Chinese Simplified")},
- {SUBTITLE_ENCODING_GB2312, "GB2312", N_("Chinese Simplified")},
- {SUBTITLE_ENCODING_GBK, "GBK", N_("Chinese Simplified")},
- {SUBTITLE_ENCODING_HZ, "HZ", N_("Chinese Simplified")},
-
- {SUBTITLE_ENCODING_BIG5, "BIG5", N_("Chinese Traditional")},
- {SUBTITLE_ENCODING_BIG5_HKSCS, "BIG5-HKSCS", N_("Chinese Traditional")},
- {SUBTITLE_ENCODING_EUC_TW, "EUC-TW", N_("Chinese Traditional")},
-
- {SUBTITLE_ENCODING_MAC_CROATIAN, "MAC_CROATIAN", N_("Croatian")},
-
- {SUBTITLE_ENCODING_ISO_8859_5, "ISO-8859-5", N_("Cyrillic")},
- {SUBTITLE_ENCODING_IBM_855, "IBM855", N_("Cyrillic")},
- {SUBTITLE_ENCODING_ISO_IR_111, "ISO-IR-111", N_("Cyrillic")},
- {SUBTITLE_ENCODING_KOI8_R, "KOI8-R", N_("Cyrillic")},
- {SUBTITLE_ENCODING_MAC_CYRILLIC, "MAC-CYRILLIC", N_("Cyrillic")},
- {SUBTITLE_ENCODING_WINDOWS_1251, "WINDOWS-1251", N_("Cyrillic")},
-
- {SUBTITLE_ENCODING_CP_866, "CP866", N_("Cyrillic/Russian")},
-
- {SUBTITLE_ENCODING_MAC_UKRAINIAN, "MAC_UKRAINIAN", N_("Cyrillic/Ukrainian")},
- {SUBTITLE_ENCODING_KOI8_U, "KOI8-U", N_("Cyrillic/Ukrainian")},
-
- {SUBTITLE_ENCODING_GEOSTD8, "GEORGIAN-PS", N_("Georgian")},
-
- {SUBTITLE_ENCODING_ISO_8859_7, "ISO-8859-7", N_("Greek")},
- {SUBTITLE_ENCODING_MAC_GREEK, "MAC_GREEK", N_("Greek")},
- {SUBTITLE_ENCODING_WINDOWS_1253, "WINDOWS-1253", N_("Greek")},
-
- {SUBTITLE_ENCODING_MAC_GUJARATI, "MAC_GUJARATI", N_("Gujarati")},
-
- {SUBTITLE_ENCODING_MAC_GURMUKHI, "MAC_GURMUKHI", N_("Gurmukhi")},
-
- {SUBTITLE_ENCODING_ISO_8859_8_I, "ISO-8859-8-I", N_("Hebrew")},
- {SUBTITLE_ENCODING_IBM_862, "IBM862", N_("Hebrew")},
- {SUBTITLE_ENCODING_MAC_HEBREW, "MAC_HEBREW", N_("Hebrew")},
- {SUBTITLE_ENCODING_WINDOWS_1255, "WINDOWS-1255", N_("Hebrew")},
-
- {SUBTITLE_ENCODING_ISO_8859_8, "ISO-8859-8", N_("Hebrew Visual")},
-
- {SUBTITLE_ENCODING_MAC_DEVANAGARI, "MAC_DEVANAGARI", N_("Hindi")},
-
- {SUBTITLE_ENCODING_MAC_ICELANDIC, "MAC_ICELANDIC", N_("Icelandic")},
-
- {SUBTITLE_ENCODING_EUC_JP, "EUC-JP", N_("Japanese")},
- {SUBTITLE_ENCODING_ISO_2022_JP, "ISO2022JP", N_("Japanese")},
- {SUBTITLE_ENCODING_SHIFT_JIS, "SHIFT-JIS", N_("Japanese")},
-
- {SUBTITLE_ENCODING_EUC_KR, "EUC-KR", N_("Korean")},
- {SUBTITLE_ENCODING_ISO_2022_KR, "ISO2022KR", N_("Korean")},
- {SUBTITLE_ENCODING_JOHAB, "JOHAB", N_("Korean")},
- {SUBTITLE_ENCODING_UHC, "UHC", N_("Korean")},
-
- {SUBTITLE_ENCODING_ISO_8859_10, "ISO-8859-10", N_("Nordic")},
-
- {SUBTITLE_ENCODING_MAC_FARSI, "MAC_FARSI", N_("Persian")},
-
- {SUBTITLE_ENCODING_ISO_8859_16, "ISO-8859-16", N_("Romanian")},
- {SUBTITLE_ENCODING_MAC_ROMANIAN, "MAC_ROMANIAN", N_("Romanian")},
-
- {SUBTITLE_ENCODING_ISO_8859_3, "ISO-8859-3", N_("South European")},
-
- {SUBTITLE_ENCODING_TIS_620, "TIS-620", N_("Thai")},
-
- {SUBTITLE_ENCODING_ISO_8859_9, "ISO-8859-9", N_("Turkish")},
- {SUBTITLE_ENCODING_IBM_857, "IBM857", N_("Turkish")},
- {SUBTITLE_ENCODING_MAC_TURKISH, "MAC_TURKISH", N_("Turkish")},
- {SUBTITLE_ENCODING_WINDOWS_1254, "WINDOWS-1254", N_("Turkish")},
-
- {SUBTITLE_ENCODING_UTF_7, "UTF-7", N_("Unicode")},
- {SUBTITLE_ENCODING_UTF_8, "UTF-8", N_("Unicode")},
- {SUBTITLE_ENCODING_UTF_16, "UTF-16", N_("Unicode")},
- {SUBTITLE_ENCODING_UCS_2, "UCS-2", N_("Unicode")},
- {SUBTITLE_ENCODING_UCS_4, "UCS-4", N_("Unicode")},
-
- {SUBTITLE_ENCODING_ISO_8859_1, "ISO-8859-1", N_("Western")},
- {SUBTITLE_ENCODING_ISO_8859_15, "ISO-8859-15", N_("Western")},
- {SUBTITLE_ENCODING_IBM_850, "IBM850", N_("Western")},
- {SUBTITLE_ENCODING_MAC_ROMAN, "MAC_ROMAN", N_("Western")},
- {SUBTITLE_ENCODING_WINDOWS_1252, "WINDOWS-1252", N_("Western")},
-
- {SUBTITLE_ENCODING_TCVN, "TCVN", N_("Vietnamese")},
- {SUBTITLE_ENCODING_VISCII, "VISCII", N_("Vietnamese")},
- {SUBTITLE_ENCODING_WINDOWS_1258, "WINDOWS-1258", N_("Vietnamese")},
-
- {SUBTITLE_ENCODING_CURRENT_LOCALE, NULL, N_("Current Locale")}
-};
-
-static gboolean
-gconf_get_bool (GConfClient *client,
- const gchar *key)
-{
- gboolean value = FALSE;
- gchar *tmp = NULL;
-
- tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key);
-
- value = gconf_client_get_bool (client, tmp, NULL);
-
- if (tmp)
- g_free (tmp);
-
- return value;
-}
-
-static void
-gconf_set_bool (GConfClient *client,
- const gchar *key,
- gboolean value)
-{
- gchar *tmp = NULL;
-
- tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key);
-
- gconf_client_set_bool (client, tmp, value, NULL);
-
- if (tmp)
- g_free (tmp);
-}
-
-static gchar *
-gconf_get_string (GConfClient *client,
- gchar *key)
-{
- gchar *value = FALSE;
- gchar *tmp = NULL;
-
- tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key);
-
- value = gconf_client_get_string (client, tmp, NULL);
-
- if (tmp)
- g_free (tmp);
-
- return value;
-}
-
-static void
-gconf_set_string (GConfClient *client,
- gchar *key,
- const gchar *value)
-{
- gchar *tmp = NULL;
-
- tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key);
-
- if (value)
- gconf_client_set_string (client, tmp, value, NULL);
- else
- gconf_client_unset (client, tmp, NULL);
-
- if (tmp)
- g_free (tmp);
-}
-
-static gboolean
-is_internal_font (const gchar * name)
-{
- /* FIXME Extremally BAD BAD BAD way of doing things */
-
- return strcmp (name, "DeviceSymbols") == 0
- || strcmp(name, "Nokia Smiley") == 0;
-}
-
-static void
-filter_out_internal_fonts (PangoFontFamily **families,
- int *n_families)
-{
- int i;
- int n; /* counts valid fonts */
- const gchar * name = NULL;
-
- for (i = 0, n = 0; i < * n_families; i++) {
- name = pango_font_family_get_name (families[i]);
-
- if(!is_internal_font(name)) {
- if (i != n) { /* there are filtered out families */
- families[n] = families[i]; /* shift the current family */
- }
- n++; /* count one more valid */
- }
- } /* foreach font family */
-
- *n_families = n;
-}
-
-static int
-cmp_families (const void *a,
- const void *b)
-{
- const char *a_name = pango_font_family_get_name (* (PangoFontFamily **) a);
- const char *b_name = pango_font_family_get_name (* (PangoFontFamily **) b);
-
- return g_utf8_collate (a_name, b_name);
-}
-
-static int
-cmp_encodings (const void *a,
- const void *b)
-{
- const SubtitleEncoding *a_encoding = (SubtitleEncoding *) a;
- const SubtitleEncoding *b_encoding = (SubtitleEncoding *) b;
-
- return g_utf8_collate (_(a_encoding->name), _(b_encoding->name));
-}
-
-static void
-font_selector_dialog (HildonButton *button,
- gpointer user_data)
-{
- GtkWidget *dialog, *hbox, *family_selector, *style_selector, *size_selector;
- gint index = 0;
- const gchar *font = NULL;
- PangoFontDescription *font_desc = NULL;
- PangoFontFamily **families;
- gint n_families = 0;
- PangoWeight pango_weight;
- PangoStyle pango_style;
-
- font = hildon_button_get_value (HILDON_BUTTON (button));
- if (font == NULL)
- return;
-
- font_desc = pango_font_description_from_string (font);
-
- dialog = gtk_dialog_new ();
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- gtk_window_set_title (GTK_WINDOW (dialog), _("Font"));
- gtk_dialog_add_button(GTK_DIALOG (dialog), "OK", GTK_RESPONSE_ACCEPT);
- gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 400);
-
- hbox = gtk_hbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
-
- /* font family selector */
- family_selector = hildon_touch_selector_new_text ();
- gtk_box_pack_start (GTK_BOX (hbox), family_selector, TRUE, TRUE, 0);
-
- pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (dialog)),
- &families, &n_families);
-
- filter_out_internal_fonts (families, &n_families);
-
- qsort (families, n_families, sizeof(PangoFontFamily *), cmp_families);
-
- for (index = 0; index < n_families; index++) {
- const gchar *family = pango_font_family_get_name (families[index]);
- hildon_touch_selector_insert_text (HILDON_TOUCH_SELECTOR (family_selector),
- index, family);
-
- if (strcmp (family, pango_font_description_get_family (font_desc)) == 0) {
- hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (family_selector), 0,
- index);
- hildon_touch_selector_center_on_selected (HILDON_TOUCH_SELECTOR (family_selector));
- }
- }
- g_free (families);
-
- /* font style selector */
- style_selector = hildon_touch_selector_new_text ();
- gtk_widget_set_size_request (style_selector, 200, -1);
- gtk_box_pack_start (GTK_BOX (hbox), style_selector, FALSE, TRUE, 0);
-
- index = 0;
- while (index < FONT_STYLE_LAST) {
- const gchar *style = g_strdup_printf ("%s", _(font_styles[index].name));
- hildon_touch_selector_insert_text (HILDON_TOUCH_SELECTOR (style_selector),
- font_styles[index].index, style);
- index++;
- }
- pango_weight = pango_font_description_get_weight (font_desc);
- pango_style = pango_font_description_get_style (font_desc);
-
- if (pango_weight == PANGO_WEIGHT_NORMAL) {
- if (pango_style == PANGO_STYLE_NORMAL) {
- hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (style_selector), 0,
- FONT_STYLE_REGULAR);
- } else {
- hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (style_selector), 0,
- FONT_STYLE_ITALIC);
- }
- } else {
- if (pango_style == PANGO_STYLE_NORMAL) {
- hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (style_selector), 0,
- FONT_STYLE_BOLD);
- } else {
- hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (style_selector), 0,
- FONT_STYLE_ITALIC_BOLD);
- }
- }
- hildon_touch_selector_center_on_selected (HILDON_TOUCH_SELECTOR (style_selector));
-
- /* font size selector */
- size_selector = hildon_touch_selector_new_text ();
- gtk_widget_set_size_request (size_selector, 100, -1);
- gtk_box_pack_start (GTK_BOX (hbox), size_selector, FALSE, TRUE, 0);
-
- index = 0;
- while (font_sizes[index] != -1) {
- const gchar *size = g_strdup_printf ("%d", font_sizes[index]);
- hildon_touch_selector_insert_text (HILDON_TOUCH_SELECTOR (size_selector),
- index, size);
-
- if (font_sizes[index] == (pango_font_description_get_size (font_desc) / PANGO_SCALE)) {
- hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (size_selector), 0,
- index);
- hildon_touch_selector_center_on_selected (HILDON_TOUCH_SELECTOR (size_selector));
- }
-
- index++;
- }
-
- /* Run the dialog */
- gtk_widget_show_all (GTK_WIDGET (dialog));
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
- if (font_desc)
- pango_font_description_free (font_desc);
-
- font_desc = pango_font_description_new ();
-
- /* set font family */
- pango_font_description_set_family (font_desc,
- hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (family_selector)));
-
- /* set font style */
- switch (hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (style_selector), 0)) {
- case FONT_STYLE_REGULAR:
- pango_font_description_set_style (font_desc, PANGO_STYLE_NORMAL);
- pango_font_description_set_weight (font_desc, PANGO_WEIGHT_NORMAL);
- break;
-
- case FONT_STYLE_ITALIC:
- pango_font_description_set_style (font_desc, PANGO_STYLE_ITALIC);
- pango_font_description_set_weight (font_desc, PANGO_WEIGHT_NORMAL);
- break;
-
- case FONT_STYLE_BOLD:
- pango_font_description_set_style (font_desc, PANGO_STYLE_NORMAL);
- pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
- break;
-
- case FONT_STYLE_ITALIC_BOLD:
- pango_font_description_set_style (font_desc, PANGO_STYLE_ITALIC);
- pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
- break;
- }
-
- /* set font size */
- pango_font_description_set_size (font_desc,
- font_sizes[hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (size_selector), 0)] * PANGO_SCALE);
-
- hildon_button_set_value (HILDON_BUTTON (button), pango_font_description_to_string (font_desc));
- }
-
- if (font_desc)
- pango_font_description_free (font_desc);
-
- gtk_widget_destroy(GTK_WIDGET(dialog));
-}
-
-
-static GtkWidget *
-create_encoding_selector (void)
-{
- GtkWidget *selector;
- gint index = 0;
-
- selector = hildon_touch_selector_new_text ();
-
- qsort (encodings, SUBTITLE_ENCODING_LAST - 1, sizeof (SubtitleEncoding), cmp_encodings);
-
- while (index < SUBTITLE_ENCODING_LAST) {
- const gchar *encoding = NULL;
-
- if (encodings[index].charset) {
- encoding = g_strdup_printf ("%s (%s)", _(encodings[index].name),
- encodings[index].charset);
- } else {
- encoding = g_strdup_printf ("%s", _(encodings[index].name));
- }
-
- hildon_touch_selector_insert_text (HILDON_TOUCH_SELECTOR (selector),
- index,
- encoding);
- index++;
- }
-
- return selector;
-}
-
-static GtkWidget *
-create_autoload_subtitles_button (GConfClient *gconf_client)
-{
- GtkWidget *button;
- gboolean autoload_subtitles = FALSE;
-
- button = hildon_check_button_new (HILDON_SIZE_FINGER_HEIGHT);
- gtk_button_set_label (GTK_BUTTON (button), _("Automatically load subtitle files"));
-
- autoload_subtitles = gconf_get_bool (gconf_client, "autoload_subtitles");
- if (autoload_subtitles)
- hildon_check_button_set_active (HILDON_CHECK_BUTTON (button), TRUE);
- else
- hildon_check_button_set_active (HILDON_CHECK_BUTTON (button), FALSE);
-
- return button;
-}
-
-static void
-save_autoload_subtitles (GConfClient *gconf_client,
- GtkWidget *widget)
-{
- if (hildon_check_button_get_active (HILDON_CHECK_BUTTON (widget)))
- gconf_set_bool (gconf_client, "autoload_subtitles", TRUE);
- else
- gconf_set_bool (gconf_client, "autoload_subtitles", FALSE);
-}
-
-static GtkWidget *
-create_subtitles_font_button (GConfClient *gconf_client)
-{
- GtkWidget *button;
- const gchar *font = NULL;
-
- button = hildon_button_new (HILDON_SIZE_FINGER_HEIGHT,
- HILDON_BUTTON_ARRANGEMENT_VERTICAL);
- hildon_button_set_title (HILDON_BUTTON (button), _("Font"));
- hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 0.0);
- hildon_button_set_title_alignment (HILDON_BUTTON(button), 0.0, 0.5);
- hildon_button_set_value_alignment (HILDON_BUTTON (button), 0.0, 0.5);
- hildon_button_set_style (HILDON_BUTTON (button), HILDON_BUTTON_STYLE_PICKER);
-
- font = gconf_get_string (gconf_client, "subtitle_font");
- if (font) {
- hildon_button_set_value (HILDON_BUTTON (button), font);
- } else {
- hildon_button_set_value (HILDON_BUTTON (button), "Sans Bold 18");
- }
-
- g_signal_connect (button, "clicked", G_CALLBACK (font_selector_dialog),
- NULL);
-
- return button;
-}
-
-static void
-save_subtitles_font (GConfClient *gconf_client,
- GtkWidget *widget)
-{
- const gchar *font = NULL;
-
- font = hildon_button_get_value (HILDON_BUTTON (widget));
- gconf_set_string (gconf_client, "subtitle_font", font);
-}
-
-static GtkWidget *
-create_subtitles_encoding_button (GConfClient *gconf_client)
-{
- GtkWidget *button, *selector;
- const gchar *encoding = NULL;
-
- button = hildon_picker_button_new (HILDON_SIZE_FINGER_HEIGHT,
- HILDON_BUTTON_ARRANGEMENT_VERTICAL);
- hildon_button_set_title (HILDON_BUTTON (button), _("Encoding"));
- hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 0.0);
- hildon_button_set_title_alignment (HILDON_BUTTON(button), 0.0, 0.5);
- hildon_button_set_value_alignment (HILDON_BUTTON (button), 0.0, 0.5);
-
- selector = create_encoding_selector ();
- hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button),
- HILDON_TOUCH_SELECTOR (selector));
-
- encoding = gconf_get_string (gconf_client, "subtitle_encoding");
- if (encoding) {
- gint index = 0;
-
- while (index < SUBTITLE_ENCODING_LAST) {
- if (encodings[index].charset) {
- if (strcmp (encodings[index].charset, encoding) == 0) {
- hildon_picker_button_set_active (HILDON_PICKER_BUTTON (button),
- index);
- break;
- }
- }
- index++;
- }
- } else {
- hildon_picker_button_set_active (HILDON_PICKER_BUTTON (button),
- SUBTITLE_ENCODING_CURRENT_LOCALE);
- }
-
- return button;
-}
-
-static void
-save_subtitles_encoding (GConfClient *gconf_client,
- GtkWidget *widget)
-{
- gint encoding = 0, index = 0;
-
- encoding = hildon_picker_button_get_active (HILDON_PICKER_BUTTON (widget));
-
- while (index < SUBTITLE_ENCODING_LAST) {
- if (encoding == index) {
- gconf_set_string (gconf_client, "subtitle_encoding",
- encodings[index].charset);
- break;
- }
- index++;
- }
-}
-
-osso_return_t
-execute (osso_context_t *osso,
- gpointer data,
- gboolean user_activated)
-{
- GConfClient *gconf_client = NULL;
- GtkWidget *dialog, *vbox, *autoload_subtitles_button;
- GtkWidget *subtitles_font_button, *subtitles_encoding_button;
-
- gconf_client = gconf_client_get_default ();
- if (gconf_client == NULL) {
- return OSSO_ERROR;
- }
-
- dialog = gtk_dialog_new ();
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data));
- gtk_window_set_title (GTK_WINDOW (dialog), _("Subtitles"));
- gtk_dialog_add_button(GTK_DIALOG (dialog), _HL("wdgt_bd_save"), GTK_RESPONSE_ACCEPT);
-
- vbox = gtk_vbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
-
- /* autoload subtitles button */
- autoload_subtitles_button = create_autoload_subtitles_button (gconf_client);
- gtk_box_pack_start (GTK_BOX (vbox), autoload_subtitles_button, TRUE, TRUE, 0);
-
- /* font selector */
- subtitles_font_button = create_subtitles_font_button (gconf_client);
- gtk_box_pack_start (GTK_BOX (vbox), subtitles_font_button, TRUE, TRUE, 0);
-
- /* font encoding */
- subtitles_encoding_button = create_subtitles_encoding_button (gconf_client);
- gtk_box_pack_start (GTK_BOX (vbox), subtitles_encoding_button, TRUE, TRUE, 0);
-
- /* Run the dialog */
- gtk_widget_show_all (GTK_WIDGET (dialog));
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
- /* save autoload subtitles option */
- save_autoload_subtitles (gconf_client, autoload_subtitles_button);
-
- /* save subtitle font option */
- save_subtitles_font (gconf_client, subtitles_font_button);
-
- /* save subtitle encoding option */
- save_subtitles_encoding (gconf_client, subtitles_encoding_button);
- }
-
- gtk_widget_destroy(GTK_WIDGET(dialog));
- return OSSO_OK;
-}
-
-osso_return_t
-save_state (osso_context_t *osso,
- gpointer data)
-{
- return OSSO_OK;
-}
-
+++ /dev/null
-[Desktop Entry]
-Encoding=UTF-8
-Version=1.0
-Name=Subtitles
-Comment=Control panel to configure subtitles for mafw-gst-subtitles-renderer
-Type=HildonControlPanelPlugin
-Icon=general_video_file
-X-control-panel-plugin=libcpmpsubtitles.so
-X-Text-Domain=mafw-gst-subtitles-renderer
-Categories=extras
+++ /dev/null
-#!/bin/sh
-# Run this to generate all the initial makefiles, etc.
-
-export AUTOMAKE="automake-1.9"
-export ACLOCAL=`echo $AUTOMAKE | sed s/automake/aclocal/`
-
-glib-gettextize --copy --force
-intltoolize --automake --copy --force
-autoreconf -v -f -i || exit 1
-test -n "$NOCONFIGURE" || ./configure \
- --enable-debug --enable-maintainer-mode "$@"
+++ /dev/null
-#
-# configure.ac for MAFW gstreamer renderer library
-#
-# Author: Visa Smolander <visa.smolander@nokia.com>
-#
-# Copyright (C) 2007, 2008, 2009 Nokia. All rights reserved.
-
-AC_PREREQ([2.53])
-AC_INIT([mafw-gst-subtitles-renderer], [0.2.2010.07-2])
-
-AC_CONFIG_SRCDIR([libmafw-gst-renderer/mafw-gst-renderer.h])
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_AUX_DIR([build-aux])
-
-AM_INIT_AUTOMAKE([foreign tar-ustar])
-AM_MAINTAINER_MODE
-
-AC_DISABLE_STATIC
-
-IT_PROG_INTLTOOL([0.35])
-AC_SUBST([GETTEXT_PACKAGE], [mafw-gst-subtitles-renderer])
-AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"], [The domain to use with gettext.])
-AM_GLIB_GNU_GETTEXT()
-
-dnl Prevent AC_PROG_CC adding '-g -O2' to CFLAGS.
-SAVEDCFLAGS="$CFLAGS"
-AC_PROG_CC
-if test "x$GCC" = xyes; then
- CFLAGS="$SAVEDCFLAGS"
-fi
-
-AC_PROG_LIBTOOL
-AC_PROG_INSTALL
-
-# DISABLED_BY_DEFAULT(NAME, DESCRIPTION)
-# ---------------------------------
-# Creates a new --enable-* option, with default value `no'.
-AC_DEFUN([DISABLED_BY_DEFAULT], [dnl
- AC_ARG_ENABLE([$1], AS_HELP_STRING([--enable-$1], [$2]), [],[dnl
- m4_bpatsubst([enable_$1], [[^0-9a-z]], [_])=no])dnl
-])# DISABLED_BY_DEFAULT
-
-# ENABLED_BY_DEFAULT(NAME, DESCRIPTION)
-# ---------------------------------
-# Creates a new --disable-* option, with default value `yes'.
-AC_DEFUN([ENABLED_BY_DEFAULT], [dnl
- AC_ARG_ENABLE([$1], AS_HELP_STRING([--disable-$1], [$2]), [],[dnl
- m4_bpatsubst([enable_$1], [[^0-9a-z]], [_])=yes])dnl
-])# ENABLED_BY_DEFAULT
-
-dnl Prerequisites.
-
-GSTREAMER_VERSION=0.10.20
-
-AM_PATH_GLIB_2_0(2.15.0, [], [], [glib])
-PKG_CHECK_MODULES(DEPS,
- gobject-2.0 >= 2.0
- gstreamer-0.10 >= $GSTREAMER_VERSION
- gstreamer-plugins-base-0.10 >= $GSTREAMER_VERSION
- mafw >= 0.1
- libosso >= 2.0
- x11
- hal
- totem-plparser
- gconf-2.0 >= 2.0
- gnome-vfs-2.0
- mce
- dbus-1
-)
-
-dnl Check for GdkPixbuf, needed for dumping current frame
-GDKPIXBUF_REQUIRED=2.12.0
-AC_ARG_ENABLE(gdkpixbuf,
- AS_HELP_STRING([--disable-gdkpixbuf],
- [Disable GdkPixbuf support, required for current frame dumping]),,
- [enable_gdkpixbuf=auto])
-
-if test "x$enable_gdkpixbuf" != "xno"; then
- PKG_CHECK_MODULES(GDKPIXBUF,
- [gdk-pixbuf-2.0 >= $GDKPIXBUF_REQUIRED],
- [have_gdkpixbuf=yes],
- [have_gdkpixbuf=no])
- AC_SUBST(GDKPIXBUF_LIBS)
- AC_SUBST(GDKPIXBUF_CFLAGS)
-
- if test "x$have_gdkpixbuf" = "xyes"; then
- AC_DEFINE(HAVE_GDKPIXBUF, [], [Define if we have GdkPixbuf])
- fi
-else
- have_gdkpixbuf="no (disabled)"
-fi
-
-if test "x$enable_gdkpixbuf" = "xyes"; then
- if test "x$have_gdkpixbuf" != "xyes"; then
- AC_MSG_ERROR([Couldn't find GdkPixbuf >= $GDKPIXBUF_REQUIRED.])
- fi
-fi
-
-AM_CONDITIONAL(HAVE_GDKPIXBUF, test "x$have_gdkpixbuf" = "xyes")
-
-
-dnl Check for Conic, needed connection error handling
-CONIC_REQUIRED=0.16
-AC_ARG_ENABLE(conic,
- AS_HELP_STRING([--disable-conic],
- [Disable Conic support, required to handle network errors]),,
- [enable_conic=auto])
-
-if test "x$enable_conic" != "xno"; then
- PKG_CHECK_MODULES(CONIC,
- [conic >= $CONIC_REQUIRED],
- [have_conic=yes],
- [have_conic=no])
- AC_SUBST(CONIC_LIBS)
- AC_SUBST(CONIC_CFLAGS)
-
- if test "x$have_conic" = "xyes"; then
- AC_DEFINE(HAVE_CONIC, [], [Define if we have Conic])
- fi
-else
- have_conic="no (disabled)"
-fi
-
-if test "x$enable_conic" = "xyes"; then
- if test "x$have_conic" != "xyes"; then
- AC_MSG_ERROR([Couldn't find Conic >= $CONIC_REQUIRED.])
- fi
-fi
-
-AM_CONDITIONAL(HAVE_CONIC, test "x$have_conic" = "xyes")
-
-
-
-plugindir=`$PKG_CONFIG --variable=plugindir mafw`
-AC_SUBST(plugindir)
-
-dnl Default compile flags. (NOTE: CFLAGS is reserved for the user!)
-
-AC_SUBST([_CFLAGS])
-AC_SUBST([_LDFLAGS])
-_CFLAGS="-Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations"
-_CFLAGS="$_CFLAGS -ggdb3"
-
-dnl Configure-time options.
-
-dnl Debugging.
-DISABLED_BY_DEFAULT([debug], [compile with debug flags and extra output])
-if test "x$enable_debug" = xyes; then
- AC_DEFINE([MAFW_DEBUG], [1], [Enable debugging related parts.])
- _CFLAGS="$_CFLAGS -O0 -Werror -DGTK_DISABLE_DEPRECATED"
-else
- AC_DEFINE([G_DEBUG_DISABLE], [1], [Disable g_debug() calls.])
- _CFLAGS="$_CFLAGS -O2"
-fi
-AS_IF([test "x$enable_debug" = xyes],
- [AC_DEFINE([MAFW_DEBUG], [1], [Enable extra debug messages])
- CFLAGS="$CFLAGS -Werror -O0 -ggdb3 -DGTK_DISABLE_DEPRECATED"],
- [AC_DEFINE([G_DEBUG_DISABLE], [1], [Disable g_debug calls])
- CFLAGS="$CFLAGS -O2"])
-
-
-dnl Tests.
-DISABLED_BY_DEFAULT([tests], [disable unit tests])
-if test "x${SBOX_DPKG_INST_ARCH}" = "xarmel"; then
- AC_MSG_WARN([Tests are disabled for compilation in armel])
- enable_tests="no"
-fi
-if test "x$enable_tests" = xyes; then
- PKG_CHECK_MODULES(CHECKMORE, [checkmore, check >= 0.9.4])
- if test -z "$CHECKMORE_LIBS"; then
- AC_MSG_WARN([checkmore is needed for unit tests!])
- fi
-fi
-AM_CONDITIONAL(ENABLE_TESTS,
- [test "x$enable_tests" = xyes && test -n "$CHECKMORE_LIBS"])
-
-dnl Volume handling
-if test "x${SBOX_DPKG_INST_ARCH}" = "xi386"; then
- DISABLED_BY_DEFAULT([pulse-volume], [enable volume handling with pulse])
-else
- ENABLED_BY_DEFAULT([pulse-volume], [enable volume handling with pulse])
-fi
-if test "x$enable_pulse_volume" = xno; then
- AC_DEFINE([MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME], [1], [Disables volume handling with pulse.])
-else
- PKG_CHECK_MODULES(VOLUME, libpulse-mainloop-glib >= 0.9.15)
-fi
-
-
-dnl Mute
-DISABLED_BY_DEFAULT([mute], [enable mute handling])
-if test "x$enable_mute" = xyes; then
- AC_DEFINE([MAFW_GST_RENDERER_ENABLE_MUTE], [1], [Enable mute.])
-fi
-
-dnl Tracing.
-DISABLED_BY_DEFAULT([tracing], [enable function instrumentation (tracing)])
-if test "x$enable_tracing" = xyes; then
- _CFLAGS="$_CFLAGS -finstrument-functions -rdynamic"
-fi
-
-dnl Coverage.
-DISABLED_BY_DEFAULT([coverage], [enable coverage data generation (gcov)])
-if test "x$enable_coverage" = xyes; then
- AC_PATH_PROG(LCOV, [lcov], [lcov])
- if test "x$LCOV" = x; then
- echo You need to install lcov to get actual reports!
- echo See http://ltp.sf.net/coverage/lcov.php
- fi
- if test "x$SBOX_USE_CCACHE" == xyes; then
- AC_MSG_ERROR([Please set SBOX_USE_CCACHE=no to use coverage.])
- fi
- _CFLAGS="$_CFLAGS -fprofile-arcs -ftest-coverage"
- _LDFLAGS="$_LDFLAGS -g -lgcov"
-fi
-AM_CONDITIONAL(ENABLE_COVERAGE,
- [test "x$enable_coverage" != xno && test -n "$LCOV"])
-
-dnl Control Panel
-PKG_CHECK_MODULES([MAFW_SUBTITLES_CPA], [libosso >= 2.0
- hildon-1 >= 2.1
- hildon-control-panel
- gtk+-2.0
- gconf-2.0])
-
-CPA_PLUGINDIR=`pkg-config hildon-control-panel --variable=pluginlibdir`
-CPA_DESKTOPDIR=`pkg-config hildon-control-panel --variable=plugindesktopentrydir`
-
-AC_SUBST(MAFW_SUBTITLES_CPA_CFLAGS)
-AC_SUBST(MAFW_SUBTITLES_CPA_LIBS)
-AC_SUBST(CPA_DESKTOPDIR)
-AC_SUBST(CPA_PLUGINDIR)
-
-dnl Output files.
-
-AC_CONFIG_FILES([
- Makefile
- mafw-gst-renderer-uninstalled.pc
- libmafw-gst-renderer/Makefile
- applet/Makefile
- tests/Makefile
- debian/mafw-gst-subtitles-renderer.install
- po/Makefile.in
-])
-
-AC_OUTPUT
+++ /dev/null
-mafw-gst-subtitles-renderer (0.3.2010.24-1+0m5-2) unstable; urgency=low
-
- * Fixed Bug: 6438: Plugin makes background music stop on lock screen.
- The only solution to fix this problem was rename back MAFW GStreamer
- renderer from mafw-gst-subtitles-renderer to mafw-gst-renderer.
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 26 Oct 2010 14:50:06 +0200
-
-mafw-gst-subtitles-renderer (0.3.2010.24-1+0m5-1) unstable; urgency=low
-
- * Package updated to version mafw-gst-renderer-0.3.2010.24-1+0m5.
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Mon, 25 Oct 2010 12:58:00 +0200
-
-mafw-gst-renderer (0.3.2010.24-1+0m5) unstable; urgency=low
-
- * This entry has been added by BIFH queue processor
- version has been changed to 0.3.2010.24-1+0m5
-
- -- Pekka Rönkkö <ext-pekka.1.ronkko@nokia.com> Mon, 21 Jun 2010 14:57:08 +0300
-
-mafw-gst-renderer (0.3.2010.24-1) unstable; urgency=low
-
- * Fixes: NB#161636 - Playbin sends EOS for endless stream
-
- -- Pekka Rönkkö <ext-pekka.1.ronkko@nokia.com> Thu, 17 Jun 2010 12:05:30 +0200
-
-mafw-gst-subtitles-renderer (0.2.2010.07-2+0m5-3) unstable; urgency=low
-
- * This package should depend on gstreamer0.10-plugins-base-subtitles
- version (>= 0.10.25-0maemo14+0m5-1).
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 25 May 2010 17:12:33 +0200
-
-mafw-gst-subtitles-renderer (0.2.2010.07-2+0m5-2) unstable; urgency=low
-
- * Updated Finnish translation by mikuu.
- * Installation of this package disable mafw-gst-renderer instead of replacing it.
- (original mafw-gst-renderer will be re-enabled after uninstallation of package).
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 18 May 2010 14:35:42 +0200
-
-mafw-gst-subtitles-renderer (0.2.2010.07-2+0m5-1) unstable; urgency=low
-
- * Added Hungarian translation by Gyorgy Lakatos.
- * Package updated to version mafw-gst-renderer-0.2.2010.07-2+0m5-1.
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Wed, 5 May 2010 10:12:28 +0200
-
-mafw-gst-renderer (0.2.2010.07-2) unstable; urgency=low
-
- * Fixes: NB#156757 - Volume settings can't be changed via Volume key, Media player is playing, Tklock is On.
-
- -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Wed, 17 Feb 2010 10:09:38 +0200
-
-mafw-gst-renderer (0.2.2010.06-1) unstable; urgency=low
-
- * Fixes: NB#150064 - NP-Video:Frames not changing while performing seek operation when the video is in paused state
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Wed, 10 Feb 2010 21:43:22 +0200
-
-mafw-gst-renderer (0.2.2010.01-1) unstable; urgency=low
-
- * Version number increased in trunk.
- * A forbidden word removed from debian/changelog.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Thu, 07 Jan 2010 19:36:53 +0200
-
-mafw-gst-renderer (0.2.2009.52-2) unstable; urgency=low
-
- * Version number increased.
-
- -- Tuomas Kamarainen <tuomas.kamarainen@nokia.com> Wed, 23 Dec 2009 12:40:45 +0200
-
-mafw-gst-renderer (0.2.2009.52-1) unstable; urgency=low
-
- * Fixes: NB#149945 - mafw-gst-renderer leaks some GStreamer messages
- * Thanks to Mueller Tim for the patch.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Sun, 20 Dec 2009 22:43:29 +0200
-
-mafw-gst-renderer (0.2.2009.50-2) unstable; urgency=low
-
- * Fixes: NB#148080 - Device UI becomes very slow after long time usage of Media Player
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Thu, 10 Dec 2009 19:07:45 +0200
-
-mafw-gst-renderer (0.2.2009.50-1) unstable; urgency=low
-
- * Version and changelog updated for pre-release 0.2009.50-1
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Tue, 08 Dec 2009 09:21:47 +0200
-
-mafw-gst-renderer (0.2.2009.49-1) unstable; urgency=low
-
- * Rebuild for 2009.49-1.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Tue, 01 Dec 2009 19:27:31 +0200
-
-mafw-gst-renderer (0.2.2009.48-2) unstable; urgency=low
-
- * Pre-release PR 1.2 2009.48-2 tag.
-
- -- Tuomas Kämäräinen <tuomas.kamarainen@nokia.com> Fri, 27 Nov 2009 11:56:14 +0200
-
-mafw-gst-renderer (0.2.2009.48-1) unstable; urgency=low
-
- * Pre-release PR 1.2 2009.48-1 tag.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Tue, 24 Nov 2009 21:57:59 +0200
-
-mafw-gst-renderer (0.1.2009.47-2) unstable; urgency=low
-
- * Version increased.
-
- -- Tuomas Kamarainen <tuomas.kamarainen@nokia.com> Fri, 20 Nov 2009 13:26:19 +0300
-
-mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-5) unstable; urgency=low
-
- * Added Danish translation by Joe Hansen.
- * Added Finnish translation by Marko Vertainen.
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 16 Feb 2010 15:02:02 +0100
-
-mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-4) unstable; urgency=low
-
- * Added German translation by Philipp Zabel.
- * Backup/restore original mafw-gst-renderer on installation/uninstallation
- of mafw-gst-subtitles package.
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Wed, 27 Jan 2010 15:29:27 +0100
-
-mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-3) unstable; urgency=low
-
- * Updating of mafw-gst-subtitles-applet package was not updating
- mafw-gst-subtitles-renderer package too.
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 19 Jan 2010 15:53:19 +0100
-
-mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-2) unstable; urgency=low
-
- * Added Czech translation.
- * List of available encoding was not sorted.
- * Removed mafw-gst-subtitles-applet postinst/postrm script, because
- mafw is restared during mafw-gst-subtitles-renderer instalation.
- * Added more font sizes.
- * Nokia fonts removed from the list of filtered fonts.
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 19 Jan 2010 15:07:48 +0100
-
-mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-1) unstable; urgency=low
-
- * Added missing build dependency to hildon-control-panel-dev
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Mon, 18 Jan 2010 22:39:17 +0100
-
-mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-0) unstable; urgency=low
-
- * Added subtitles support.
- * Added Subtitles control panel applet.
-
- -- Roman Moravcik <roman.moravcik@gmail.com> Mon, 18 Jan 2010 22:09:11 +0100
-
-mafw-gst-renderer (0.1.2009.42-2) unstable; urgency=low
-
- * Version increased.
-
- -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Tue, 20 Oct 2009 13:26:36 +0300
-
-mafw-gst-renderer (0.1.2009.42-1) unstable; urgency=low
-
- * Version and changelog updated for pre-release 0.2009.42-1
- * Rebuild needed.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Mon, 12 Oct 2009 17:21:48 +0300
-
-mafw-gst-renderer (0.1.2009.40-1) unstable; urgency=low
-
- * Version and changelog updated for pre-release 0.2009.40-1
- * PR_1_1_baseline copied from trunk.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Sun, 04 Oct 2009 15:47:32 +0300
-
-mafw-gst-renderer (0.1.2009.39-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.39-1
- * Check for changes only in device having the video-out property.
- * Disabled test of pulse reconnection as it is not needed with fake volume
- manager to fix volume test
- * Changed default fake volume initialization to 0.485 instead of 1 to fix
- volume tests
- * Added return of initialized fake volume manager in an idle call to fix
- volume tests
- * Added function to reset volume to pulse pipeline in case pulse volume
- management is disabled
- * Added fake volume manager and disabled normal handling with pulse when
- pulse volume is disabled in compilation.
- * We avoid setting audiosink to the pipeline and native flags when pulse
- volume is disabled.
- * Moved checking for pulse dependency to its conditional compilation
- * Added support for conditional compilation regarding to volume in
- renderer
- * Adds a macro to round values when converting from nanoseconds to seconds.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 18 Sep 2009 14:21:32 +0300
-
-mafw-gst-renderer (0.1.2009.37-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.37-1
- * Fixes: NB#121136 - [Power Management]Device never goto power saving mode when video playback is connected to TV out
- * Fixes: NB#134730 - [PR1.1 proposal] <MemLeak> mafw-gst-renderer.c
- * Fixes: NB#134728 - [PR1.1 proposal] <MemLeak> mafw-gst-renderer-worker.c
- * Fixes: NB#134495 - [PR1.1 proposal] State changed signal does not come sometimes when stream is played
- * if for some reason client starts a resume operation
- after a seek on a stream and by the time we get the resume command we
- have not started buffering yet, make sure we signal the state change
- to playing to the client.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 04 Sep 2009 12:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.35-3) unstable; urgency=low
-
- * MAFW Sales RC4.
- * Fixes: NB#129912 - Audio playback jarring while receiving a SMS while multiple browser/applications are open.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Tue, 25 Aug 2009 14:15:34 +0300
-
-mafw-gst-renderer (0.1.2009.35-2) unstable; urgency=low
-
- * First MAFW Sales RC.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Fri, 21 Aug 2009 16:38:27 +0300
-
-mafw-gst-renderer (0.1.2009.35-1) unstable; urgency=low
-
- * Fixes: NB#129912 - Audio playback jarring while receiving a SMS while multiple browser/applications are open.
- * Increased the priority of the mafw-gst-renderer.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Thu, 20 Aug 2009 17:34:03 +0300
-
-mafw-gst-renderer (0.1.2009.34-3) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.34-3
- * Fixes: NB#132950 - Video seeking is slow most of the time
- * Check if we get a different duration that the source one and update it
- if needed in renderer
- * Added function mafw_gst_renderer_update_source_duration
- * Reworked mafw_gst_renderer_increase_playcount to use _get_source function
- * Reworked mafw_gst_renderer_get_metadata to use _get_source function
- * Created _get_source function in renderer
- * Reworked _check_duration condition into two different ifs and extracted
- duration in seconds calculation
- * Added duration to the source metadata request and kept it in the
- renderer metadata structure.
- * Duration in renderer converted in gint instead of guint to hold
- negative values
- * flag GST_SEEK_FLAG_KEY_UNIT.
- * Patch provided by Rene Stadler.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Mon, 17 Aug 2009 22:06:17 +0300
-
-mafw-gst-renderer (0.1.2009.33-3) unstable; urgency=low
-
- * Fixes: NB#131655 - UPnP: Playback starts from the first instead of playing from where we paused if left the device idle
- * Fixes: NB#131609 - Mafw-dbus-wrapper crashes. Audio cannot be heard from device's loudspeaker.
- * Replaced assertion with critical in volume manager for unsuccessful
- setting volume in pulse operations.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Thu, 13 Aug 2009 17:03:10 +0300
-
-
-mafw-gst-renderer (0.1.2009.33-2) unstable; urgency=low
-
- * Fixes: NB#128110 - Playback neither stopped nor internal mmc is mounted onto pc when connected in mass storage mode
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Mon, 10 Aug 2009 12:27:43 +0300
-
-mafw-gst-renderer (0.1.2009.33-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.33-1
- * Fixes: NB#128110 - Playback neither stopped nor internal mmc is mounted onto pc when connected in mass storage mode
- * New Build-Dependency libosso-gnomevfs2-dev added.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Wed, 05 Aug 2009 12:37:05 +0300
-
-mafw-gst-renderer (0.1.2009.32-1) unstable; urgency=low
-
- * MAFW, pre-release 0.1.2009.32-1
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Sun, 02 Aug 2009 22:32:27 +0300
-
-mafw-gst-renderer (0.1.2009.30-3) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.30-3
-
- -- Juha Kellokoski <veitikka6@gmail.com> Wed, 22 Jul 2009 14:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.30-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.30-2
- * Fixes: NB#128479 - Seeking in UPnP signals pause and keeps on playing
- * Solved problem when pausing while buffering in renderer worker
- * We activate state changes if we resume while buffering to report the
- state change to playing in renderer worker
-
- -- Juha Kellokoski <veitikka6@gmail.com> Wed, 22 Jul 2009 14:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.30-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.30-1
- * Added more debug to the _handle_buffering function in renderer worker
- * Just set pipeline to playing when finished buffering of a stream when
- seeking to avoid signalling PAUSE.
- * Added documentation in _handle_state_changed function in renderer worker
- * Added comments in _do_play function in renderer worker
- * Added comments in _finalize_startup funcion in renderer worker
- * Reworked _handle_state_changed to use GST_STATE_TRANSITION in renderer
- worker.
- * Reworked _handle_state_changed to use _do_pause in renderer worker
- * Created _do_pause function to notify the state change and get the
- current frame on pause if needed in renderer worker.
- * Removed buffering info from renderer as it was being handled by worker
- * Removed seek in pause comments as we are not using them in renderer worker
- * Simplified if condition in state managegement in renderer worker.
- * Removed state assignment because it could be done at one point in
- _handle_state_changed in renderer worker.
- * Added comments in field names in renderer worker to clarify their use
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 17 Jul 2009 14:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.28-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.28-2
- * Ref the assigned playlist
-
- -- Juha Kellokoski <veitikka6@gmail.com> Tue, 07 Jul 2009 14:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.28-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.28-1
- * Fixes: NB#123689 - mafw-dbus-wrapper-76CE-6-4559.rcore.lzo crashed
- * Ref the assigned playlist
- * Removing an unnecessary comparison.
- * Added g_debug in volume manager to indicate that it is initialized and
- return the instance
- * Changed _connect function to get an InitCbCallback in volume manager
- * Modified _reconnect function in volume manager to receive an
- InitCbCallback and propertly return the volume manager if reconnection
- happens before having connected a first time
- * Written function to create the InitCbClosure in volume manager
- * When [re-]connection to pulse fails, we log a critical and reconnect
- after 1 second
- * Modified log in renderer tests to log only errors
- * Added tests for pulseaudio reconnection in renderer
- * Removed volume tests in playing since it is not needed anymore as it
- does not depend on the playing state.
- * Added check for receiving mute when property is changed in renderer
- tests
- * In renderer tests, wait for the volume manager to be initialized when
- testing properties
- * Added pulseaudio mock to renderer tests
- * Added small code comment in renderer tests
- * Solved problem with mute not enable in renderer tests
- * Fixed problem when adding elements to a mock playlist in renderer
- tests
- * Fixed problem with playlist size initialization in playlist iterator in
- renderer that was causing problems in the tests
- * Fixed a bug in the tests when testing the stats updating
- * Fixed problem with playlist reference count in renderer tests.
- * Replaced pulsesink and xvimagesink by fakesink in renderer tests
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 03 Jul 2009 11:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.27-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.27-2
- * Fixes: NB#123701 - mafw-dbus-wrapper-76CE-6-1218.rcore.lzo crashed
- * Fixes: NB#116836 - Streaming stops after taping on Next button during paused state
- * Fixes: NB#123545 - mafw-gst-renderer get-position returns uninitialized value
- * Fixes: NB#124469 - Device going to power saving mode after seek for video streams
- * Fixes: NB#124116 - Position not progressing after seeking
- * Fixes: NB#117860 - Inability to handle multiple resource of UPnP items
- * Make sure we stay paused while buffering.
- * Always keep worker->state up-to-date.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Tue, 30 Jun 2009 14:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.27-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.27-1
- * Added function to remove the _set_timeout and used not to call it twice
- innecessarily.
- * Changed the order of adding the timeout to set the volume to pulse and
- calling the timeout immediately as that runs on the mainloop and that
- execution is delayed to that
- * Checked for NULL operation when writing volume to pulse to avoid
- crashes. Critical used instead.
- * In _ext_stream_restore2_read_cb changed assertion for critical when
- getting eol < 0 in volume manager
- * Discarded ext_stream_restore2 volume event when eol < 0. Crash avoided
-
- -- Juha Kellokoski <veitikka6@gmail.com> Thu, 25 Jun 2009 13:40:00 +0300
-
-mafw-gst-renderer (0.1.2009.26-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.26-1
- * Check for NULL in the current_metadata.
- * Removed useles warning message
- * Updating states and blanking even if we do not need to report them.
- * Move pause notification from _do_play to handle_buffering.
- * Build fix.
- * make _get_position be a state dependant function.
- On Transitioning it sets position to 0, on Stopped raises an error.
- * Improved state management in mafw-gst-renderer
- when seeking (compare new state with worker state to decide
- if we have to ignore the state transition and in any case,
- always update the worker state).
- * Activate playbin2 flags. Speeds up video start time to half.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Tue, 23 Jun 2009 14:33:24 +0300
-
-mafw-gst-renderer (0.1.2009.25-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.25-2
- * Fixes: NB#117207 - Random MAFW-DBUS-WRAPPER crashes observed
- * Fixes: NB#104213 - 'Unable to Find Media file' information note not displayed when MMC removed.
- * Fixes: NB#116426 - Renderer fails to go to pause state when media clips are seeked while streaming
- * Fixes: NB#121545 - pa_context_connect fails though flag PA_CONTEXT_NOFAIL set
- * Fixes: NB#120942 - State changed signal is not coming when play issued right after seeking with video streams
- * Extended current metadata function.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Mon, 15 Jun 2009 14:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.25-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.25-1
- * Reconnection to pulse is done using an idle call in volume manager.
- * If PLAY is issued rigtht after seek,
- signal the state change when we are done buffering. Still,
- there is a problem because we should not execute a PLAY command
- while buffering...
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 12 Jun 2009 11:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.24-3) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.24-3
- * Fixes: NB#118019 - Playing a clip of Unsupported format will stop the playback.
- * Fixes: NB#120378 - Video doesn't start to play when clicked
- * Stop setting volume if pulse is down in volume manager
- * Written small workaround for problem when getting an empty error while
- saving a pixbuf in renderer worker.
- * Log a warning message when processing an error.
- * A mafw-gst-renderer dependency version shortened to 0.9.15-1.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Wed, 10 Jun 2009 11:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.24-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.24-2
- * Added "mafw_renderer_get_current_metadata" function to the API.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Mon, 08 Jun 2009 11:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.24-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.24-1
- * Fixes: NB#120287 - Video recorded using other camera (e.g. Canon, Pentax) not playing smooth
- * Fixed debug for seekability in renderer.
- * We check always GStreamer seekability unless it is reported FALSE from
- source.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Thu, 04 Jun 2009 10:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.23-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.23-2
- * Fixes: NB#119440 - Dbus wrapper crashes when high bit rate, high resolution clips are played.
- * Fixes: NB#119613 - Random mafw-dbus-wrapper coredump generated after booting.
- * Fixes: NB#119467 - Deleted playlists are not freed.
- * Fixes: NB#118459 - Cannot play Nokia 5800 video clip
- * Fixes: NB#115776 - Renderer state changed signal are not coming when playing and seeking video
- * No need to ref the playlist in the renderer,
- the playlist manager does that already.
- * Changed to avoid setting the timeout if neither volume nor mute have
- changed in volume manager
- * Changed debug messages in volume manager
- * We ignore mute if it not enabled (default = not enabled).
- * Added option to configure.ac to disable or enable mute handling
- * Use g_error_new_literal if string is constant.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Tue, 02 Jun 2009 12:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.23-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.23-1
- * Signalling volume when reconnecting to pulse
- * Added code to reconnect to pulse when it gets disconnected.
- * Closure callback for initialization is not called if it is NULL in
- volume manager.
- * Created _connect function to connect with pulse and reworker the init
- function in volume manager.
- * Created _destroy_context function and changed _destroy_idle function to
- do it in volume manager.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 29 May 2009 10:30:00 +0300
-
-mafw-gst-renderer (0.1.2009.22-3) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.22-3
- * Use appropriate error codes when the renderer cannot create
- the playback pipeline and when there are problems with the
- video window.
- * Abort the renderer if cannot create pipeline ot sinks.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Wed, 27 May 2009 10:30:00 +0300
-
-mafw-gst-renderer (0.1.2009.22-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.22-2
- * Fixes: NB#114972 - NP: AUdio- Taping on Next or Previous song volume goes to 0 level
- * Fixes: NB#109166 - NP view - Volume bar does not popup for Hardware volume +/- key presses
- * Fixes: NB#116070 - video plays before displaying unsupported resolution error message
- * Fixes: NB#112697 - gst-renderer not listening volume change events from pulseaudio
- * Fixes: NB#118001 - seekbar is disabled after playing a unsupported clip
- * We switch volume manager volume to the just set so we signal it directly
- when the change is requested. We don't signal any change in the volume
- subscription if we have and operation in progress.
- * We keep the pa_operation when writing the volume and cancel it and unref
- it when a new one comes.
- * Changed requested_* structure members to current_* in volume manager
- * Renamed volume and mute structure members to pulse_* in volume manager.
- * Fixed a small problem with mute. We were forgetting to set it when
- sending it to pulse.
- * Changed timeout interval for setting volume to 200ms.
- * We just change the volume as soon as we get the first call and then we
- add the timeout to filter following changes.
- * Improved rounding volumes as we signalled different ones from the one we
- were setting.
- * Added protections to public methods so that they are not called when
- volume manager is not alive yet.
- * Minor changes when falling back to playbin usage.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Mon, 25 May 2009 12:21:24 +0300
-
-mafw-gst-renderer (0.1.2009.22-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.22-1
- * If we fallback to use playbin instead of playbin2, check that
- we can actually create an instance before attempting to
- set properties.
- * Changed to filter volume and mute changes to join several in a single
- call.
- * Setting property to ensure pulse role when initializing volume manager
- in renderer.
- * Separated role and its prefix for checking in volume manager in renderer
- * Added more debug to volume manager in renderer
- * Added dependencies to debian/control and configure.ac
- * Migrated volume management in worker to use pulse implementation.
- * Added code to manage volume with pulse. This code was developed in
- collaboration with Marc-André Lureau in gitorious. Link:
- http://gitorious.org/~calvaris/mafw-pulse/calvaris
- * Added compilation of volume files to Makefile.am in renderer.
- * Added empty files with licenses for volume management in renderer.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 22 May 2009 12:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.21-4) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.21-4
- * Reuse video sink component, do not create a new one every time
- we play something.
- * Ref audio and video sink before setting them, since we want them
- to persist after the pipeline has been destroyed.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Wed, 20 May 2009 11:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.21-3) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.21-3
- * Fixes: NB#104494 - Missing renderer error when video clib has high framerate
- * Fixes: NB#115514 - UPnP:After seeking the seekbar on Pause state audio/video clip started playing
- * Fixes: NB#115304 - Video playback will stop if we plug in usb cable
- * Fixes: NB#115299 - Media player seek bar comes to starting position if usb cable is pluged in
- * Properly initialize variable.
- * Use specific error codes for unsupported
- resolution and unsupported fps conditions.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Tue, 19 May 2009 10:30:00 +0300
-
-mafw-gst-renderer (0.1.2009.21-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.21-2
-
- -- Juha Kellokoski <veitikka6@gmail.com> Mon, 18 May 2009 11:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.21-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.21-1
- * Fixes: NB#117015 - video plays in windowed mode
- * Fixes: NB#100842 - seeking in aac over http fails
- * Fixes: NB#115126 - Media Player abuses Tracker API while playing songs
- * Do not reuse video sink for now, somehow it gets
- broken after some time and as a result we cannot set XID of target
- video window to use.
- * Create and configure audio and video sinks once, then provide these
- to playbin2 when a new pipeline is created.
- * Changed _handle_duration to use _check_duration and added for
- seekability too.
- * Reworked _query_duration_and_seekability into _check_duration and _check
- seekability.
- * Added timeout to query duration and seekability and changed when it was
- called.
- * Set timeout id to 0 when timeout is removed
- * Used function to compare duration in seconds instead of comparing pure
- nano seconds.
- * Added function to compare durations in seconds.
- * Query duration and seek after buffering is complete.
- * Reworked adding the timeout to use a function.
- * Modified seekability emission to be done only with changes and adapted
- to type changes.
- * Modified duration emission to be emitted only with changes.
- * Media seekability initialized to unknown when playback begins.
- * SeekabilityType renamed and moved to renderer worker.
- * Renderer worker seekability uses its type now instead of gboolean.
- * Stored duration and seek timeout id to be able to remove it later in
- renderer worker.
- * Added query for duration and seekability some seconds after going to
- PLAYING to have more accurate information from GStreamer in renreder
- worker.
- * Reworked _finalize_startup in renderer worker into _finalize_startup and
- _query_duration_and_seekability. The first uses now the second.
- * Set pulse sink's latency-time property to half of buffer-time,
- this provides double buffering capabilities and should also help
- with avoiding audio glitches. Also, removed buffering for volume
- pipeline, since that is not needed.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Thu, 14 May 2009 10:09:18 +0300
-
-mafw-gst-renderer (0.1.2009.20-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.20-1
- * Fixes: NB#107221 - Connecting and disconnecting with an AP while playing an MP3 cause audio breakage
- * Fixes: NB#114181 - Video aspect ratio is not preserved
- * Set appropriate buffering settings for audio sink
- to avoid audio glitches on certain scenarios.
- * Maintainer changed in control file.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Thu, 07 May 2009 11:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.19-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.19-1
- * Fixes: NB#108833 - [Onsite] Audio volume is turned full when song is changed
- * Fixes: NB#113464 - Dbus connection lost error message displayed in while trying to up/down volume level from MTG
- * Fixes: NB#96483 - Gstreamer renderer does not change from GST_STATE_PAUSED to GST_STATE_READY after timeout
- * Fixes: NB#104494 - Missing renderer error when video clib has high framerate
- * Fixes: NB#110654 - mafw-dbus-wrapper prints about a critical error
- * Fixes: NB#103987 - Audio playback is breaking for few seconds while playing mms live streams.
- * Fixes power management issues caused by the volume pipeline
- being always in PAUSED state. While a proper implementation
- for volume management is not in place, this temporal fix
- workarounds the problem by setting it to PAUSED on demand
- when global volume has to be read, and then setting it back
- to READY.
- * Do not check video caps on prepare-xwindow-id, instead wait
- for prerolling to finish, otherwise caps are not set yet.
- * Use 'g_timeout_add_seconds' where possible.
- * Added monitor volume hack again, but when going to playing instead of
- stopping.
- * Revert "Added monitor_hack again but called only when stopping the worker."
- * Added monitor_hack again but called only when stopping the worker.
- * Revert "Added dirty hack to be aware of the volume changes that don't
- happen"
- * Revert "Hack to monitor volume does not return TRUE, but FALSE and
- reinstalls"
- * Improved playlist-change handling
- * Hack to monitor volume does not return TRUE, but FALSE and reinstalls
- the timeout not to do it at regular intervals, but a timeout after last
- callback is run.
- * Do not go to PLAYING state until we are done buffering.
- * Disable native flags in playbin2 temporarily since this is causing
- trouble with some videos. Also, allow videos with resolution
- up to 848x576.
- * Added dirty hack to be aware of the volume changes that don't happen
- inside mafw code. As soon as GStreamer adds notify::volume signals, we
- have to remove this immediately.
- * Setting volume when playing is done only for playback volume.
- * Moved volume management from playback pipeline to volume pipeline. We
- don't update the volume pipeline because it should be updated but we do it
- with the playback one because it has always to be set up.
- * Moved listening to volume signals from playback pipeline to volume
- pipeline in renderer
- * Added customized pipeline to always listen to volume changes in renderer
- * Added support to distinguish between audio and video codec errors.
- * Fixed critical warning message.
- * When we get the ckey coming from the sync bus to the async bus, we check
- the caps and raise an error if they are not suitable.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Thu, 30 Apr 2009 10:00:00 +0300
-
-mafw-gst-renderer (0.1.2009.18-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.18-1
-
- -- Juha Kellokoski <veitikka6@gmail.com> Thu, 23 Apr 2009 15:30:00 +0300
-
-mafw-gst-renderer (0.1.2009.17-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.17-2
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 17 Apr 2009 09:18:07 +0300
-
-mafw-gst-renderer (0.1.2009.17-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.17-1
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Wed, 15 Apr 2009 15:59:15 +0300
-
-mafw-gst-renderer (0.1.2009.16-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.16-2
- * Fixes: NB#110043 - Mafw-dbus-wrapper crash is observed while switching between proxy playlist in a particular case
- * Fixes: NB#108725 - DLNA CTT tool gives a failed verdict on "MT HTTP Header: Range - use in HEAD/GET requests"
- * Added pre-unmount signal handling in the renderer.
- * Added debug for seekability in renderer.
- * Renderer uses now as first choice seekability coming from source and if not
- defined, we query GStreamer as it happened so far.
- * Added requesting seekability to source in renderer.
- * Added support for seekability coming from source in renderer.
- * Removed assumption of positive seekability for local files with known
- duration.
- * If GStreamer cannot answer to a request for seekability, we assume it is
- not.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Tue, 14 Apr 2009 15:06:34 +0300
-
-mafw-gst-renderer (0.1.2009.16-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.16-1
- * All tags reported by Gst are referenced and freed later on,
- when they have emitted to clients. However, _emit_renderer_art
- was obtaining a reference to a tag value and freeing that
- reference when done, leading to a double unref later on.
-
- -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Wed, 08 Apr 2009 12:41:14 +0300
-
-mafw-gst-renderer (0.1.2009.15-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.15-2
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 03 Apr 2009 09:17:14 +0300
-
-mafw-gst-renderer (0.1.2009.15-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.15-1
- * Fixes: NB#106136 - Metadata not shown properly for radio stations.
- * Added transport-actions property. For the moment contains information
- about Seek operation.
- * Unit test disabled by default for system integration purposes.
- * Some tags are detected when Gstreamer is already
- in GST_STATE_PLAYING, so in this case, emit them right away, otherwise
- they are never emitted to the UI.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 03 Apr 2009 09:17:14 +0300
-
-mafw-gst-renderer (0.1.2009.14-4) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.14-4
- * Update playcount id should be 0 while _notify_play is run in renderer
- so it doesn have sense checking about that
- * Removed update_playcount_needed as behavior can be accoplished only with
- timeout id in renderer.
- * Moved the code to remove the update_playcount to the state class to fix
- state pattern.
- * _update_playcount_cb made public inside the renderer to be called from other
- parts of it.
- * Moved the code to add the timeout to state-transitioning.
- * Moved the code from the state notify_eos in the base renderer to the
- state-playing.
- * Added initialization of the update_playcount structures in renderer.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Wed, 01 Apr 2009 09:34:16 +0300
-
-mafw-gst-renderer (0.1.2009.14-3) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.14-3
- * Fixes: NB#107595 - Xid not set error comes when video is played to the end and then played again with media player
- * Removed guessing the seekability from renderer in favor of only GStreamer
- query.
- * Setting pipeline to NULL without checking for async changes as it
- cannot happen according to Stefan comments.
- * Must always stop() on EOS when there are
- no more items to play. This frees X resources if playing video,
- otherwise setting a new Xid afterward leads to a BadWindow X
- error.
- * Enabling gstreamer optimization flags
- * Creating pipeline at startup and, soon after the playback has ended, to
- speed up the starting of the playback
-
- -- Juha Kellokoski <veitikka6@gmail.com> Tue, 31 Mar 2009 09:20:00 +0200
-
-mafw-gst-renderer (0.1.2009.14-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.14-2
-
- -- Juha Kellokoski <veitikka6@gmail.com> Mon, 30 Mar 2009 09:23:13 +0200
-
-mafw-gst-renderer (0.1.2009.14-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.14-1
-
- -- Juha Kellokoski <veitikka6@gmail.com> Fri, 27 Mar 2009 09:30:00 +0200
-
-mafw-gst-renderer (0.1.2009.13-5) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.13-5
- * Fixes: NB#102972 - Pause AAC clip from UPnP server timer shows as 00:00
- * Changed _notify_buffer_status in state-transitioning in renderer
- to use the do_notify_buffer status as code was the same after removing timer
- * Removed timer support from renderer utils
- * Removed timer handling in renderer.
- * Removed timer use from renderer get_position
- * Changed API to return gint instead if guint in the get_position
- callback
- * Set Visa as integrator.
- * Upgrade copyright year.
- * Add headers for Makefile.am and configure.ac files.
- * Set Visa Smolander as the contact person in headers.
-
- -- Juha Kellokoski <veitikka6@gmail.com> Thu, 26 Mar 2009 09:53:00 +0200
-
-mafw-gst-renderer (0.1.2009.13-4) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.13-4
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Wed, 25 Mar 2009 09:16:48 +0200
-
-mafw-gst-renderer (0.1.2009.13-3) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.13-3
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Tue, 24 Mar 2009 09:23:08 +0200
-
-mafw-gst-renderer (0.1.2009.12-4) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.12-4
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Wed, 18 Mar 2009 09:17:01 +0200
-
-mafw-gst-renderer (0.1.2009.12-3) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.12-3
- * Fixed CID 610
- * Fixed CID 2592
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Wed, 18 Mar 2009 09:17:01 +0200
-
-mafw-gst-renderer (0.1.2009.12-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.12-2
- * Fixes: NB#102172 - Total clip duration shown wrongly for vbr clips.
- * Fixes: NB#105468 - Mafw-dbus-wrapper freezes when commands are given consecutively
- * Corrected the double tag emission when pausing in transitioning
- and going to GST_STATE_READY in renderer worker
- * Moved _free_taglist functions above in renderer worker
- * Removed tag_list as global variable to be inside the renderer
- worker
- * Modified other functions according this point
- * Moved _add_ready_timeout from _construct_pipeline to _do_play
- in renderer to allow us going to ready just after building the pipeline
- because in the other case we hadn't received the seekability yet.
- * Solved a memory leak when freeing the tag list in renderer worker
- * Changed going to GST_STATE_READY only for seekable streams in renderer
- worker
- * Code to go to GST_STATE_READY after sometime in PAUSED in renderer
- worker reactivated
- * Added checks for NULL buffers when emitting the current frame on
- paused.
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Tue, 17 Mar 2009 09:21:54 +0200
-
-mafw-gst-renderer (0.1.2009.11-6) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.11-6
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 12 Mar 2009 09:13:36 +0200
-
-mafw-gst-renderer (0.1.2009.11-5) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.11-5
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 12 Mar 2009 09:13:36 +0200
-
-mafw-gst-renderer (0.1.2009.11-4) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.11-4
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Wed, 11 Mar 2009 09:09:57 +0200
-
-mafw-gst-renderer (0.1.2009.11-3) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.11-3
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Tue, 10 Mar 2009 09:12:41 +0200
-
-mafw-gst-renderer (0.1.2009.11-2) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.11-2
- * Fixes: NB#104680 - System UI freezed while playing high resolution albumart clips
- * Added buffering info test in renderer
- * Added support to get buffering information in renderer tests
- * Added tests for properties management in renderer tests
- * Solved a problem that could cause some race conditions in volume handling
- in renderer worker
- * Moved _set_volume and _set_mute functions in the worker file in
- renderer.
- * Added support to manage properties values in renderer tests
- * Added test for duration emission in renderer tests
- * Added test for get_position in renderer
- * Added tests for media art emission in renderer
- * Added GStreamer tag management in renderer tests
- * Added testframe.png to renderer tests
- * Activated and fixed video tests compilation in renderer
- * Added functions to metadata checks in renderer tests.
- * Added error policy tests in renderer
- * Added support in renderer tests to receive expected error callbacks
- * Fixed problem with update lastplayed in renderer tests.
- * Solved problem in playcount renderer tests.
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Mon, 09 Mar 2009 09:24:38 +0200
-
-mafw-gst-renderer (0.1.2009.11-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.11-1
- * Notify when third-party applications modify gstreamer volume.
- * Enabling unit tests to mafw-gst-renderer.
- * Update playcount and last-played when reaching EOS, or after 10 seconds.
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 05 Mar 2009 14:43:54 +0200
-
-mafw-gst-renderer (0.1.2009.10-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.10-1
- * Fixed segfault
- * Removed gstreamer0.10-selector from the mafw-gst-renderer dependencies.
- * Allow blanking when TV Out cable is plugged.
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 26 Feb 2009 14:06:24 +0200
-
-mafw-gst-renderer (0.1.2009.9-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.09-1
- * Disabling optimization flags
- * Removing helixbin usage
- * Delaying metadatas received from gstreamer
- * Preload some gst plugins at startup
- * Adding some optimization flags to the pipeline
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 19 Feb 2009 17:26:04 +0200
-
-mafw-gst-renderer (0.1.2009.8-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.08-1
- * Fixes: NB#98725
- * Fixes: NB#100158
- * Added Nokia copyright to gstcreenshot.[ch] files in renderer.
- * Made bvw_frame_conv_convert asynchronous
- * Adapted renderer worker to that conversion.
- * Reusing pipeline for color space conversion in renderer.
- * Changed raw video art saving to use bacon video widget conversion in
- mafw-gst-renderer
- * Added gstsnapshot.[ch] files to renderer to convert raw frames into
- understandable format for gdk_pixbuf
- * Changed tmp file name for gstreamer renderer emitted art
- * Changed function _save_graphic_file_from_gst_buffer to
- save an unconverted video/x-raw-rgb.
- * Revert "Fake function that copies a fake frame to test"
-
- -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 12 Feb 2009 14:22:39 +0200
-
-mafw-gst-renderer (0.1.2009.07-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.07-1
- * Changed highest resolution for fremantle
-
- -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Fri, 06 Feb 2009 08:38:37 +0200
-
-mafw-gst-renderer (0.1.2009.06-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.06-1
- * Changed highest resolution for fremantle
- * Added GTK_DISABLE_DEPRECATED parameters for mafw-tracker-source
- configure.ac. Added extended descriptions for
- * mafw-gst-renderer.
- * Build fix
-
- -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Fri, 30 Jan 2009 14:03:15 +0200
-
-mafw-gst-renderer (0.1.2009.05-1) unstable; urgency=low
-
- * MAFW gst renderer, pre-release 0.2009.05-1
- * Changing the base class of the extension objects to GInitiallyUnowned
- * Changed testframe.jpeg
-
- -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Thu, 22 Jan 2009 14:33:27 +0200
-
-mafw-gst-renderer (0.1.2009.04-1) unstable; urgency=low
-
- * MAFW, pre-release 0.2009.04-1
- * Changed testframe.jpeg
- * Reducing lintian warnings.
- * Fixes: NB#97304
- * Fixes: NB#94990
- * Fixes: NB#85894
-
- -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Fri, 16 Jan 2009 14:59:38 +0200
-
-mafw-gst-renderer (0.1.2009.03-1) unstable; urgency=low
-
- * MAFW, pre-release 0.1.2009.03-1
- * Testing the error reporting when resuming in transitioning state
- without having paused.
- * Sent a GError if trying to resume in transitioning state without
- having paused before.
- * Reset timer when stopping.
- * Remated stream_timer_* functions into media_timer_* because
- name was confusing.
- * Renamed _is_playlist into uri_is_playlist and moved to -utils in
- renderer.
- * Changed its calls to use the new name.
- * Changed condition about reporting the error when performing _do_seek.
- * Added comment about the playlist mode error handling in renderer
- worker.
- * Changed tagmap array for a GHashTable in renderer worker.
- * Removed playback mode and pl struct from global variables and added
- to worker structure.
- * Added worker as parameter to _reset_pl_info and _on_pl_entry_parsed
- in renderer because it is needed to use the parameters inside worker structure.
- * Removed old_error handler because it was not being used.
- * In renderer worker renamed:
- * NORMAL_MODE -> WORKER_MODE_SINGLE_PLAY
- * PLAYLIST_MODE -> WORKER_MODE_PLAYLIST
- * Changed _metadata_set_cb to g_debug if operation was correct or if
- it failed.
- * Reindented _update_playcount_metadata_cb parameters in renderer.
- * Logged error in _update_playcount_metadata_cb in renderer because
- it was just being ignored. This causes the tests to log the warning.
- * Added a meaningful error to a test in renderer.
- * Fixed _update_playcount_metadata_cb documentation in renderer.
- * Renamed _playcount_metadata into _update_playcount_metadata_cb in
- renderer.
- * mafw_gstreamer_renderer_get_position changed not to test for
- callback != NULL because it is already being checked in preconditions.
- * Changed mafw_gstreamer_renderer_get_status not to test callback != NULL
- because it is already checked in preconditions.
- * In mafw_gstreamer_renderer_get_status added check for callback != NULL
- in preconditions.
- * Renamed unable_play_count into play_failed_count in renderer.
- * Added G_LOG_DOMAIN for check-mafw-gstreamer-renderer.
- * Removed the CHECK-MLS traces from renderer tests.
- * Changed the G_LOG_DOMAIN for given files to have more suitable ones
- in renderer.
-
- -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Thu, 08 Jan 2009 16:13:10 +0200
-
-mafw-gst-renderer (0.1.2008.52-1) unstable; urgency=low
-
- * Renamed midas to mafw
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 22 Dec 2008 12:55:59 +0200
-
-midas-gstreamer-renderer (0.1.2008.52) unstable; urgency=low
-
- * Removing libtotem-pl-parser
- * Deactivated code of the timeout to go to ready until bug with gstreamer is clarified.
- * Added functions to add, remove and timeout function itself to switch from PAUSED to READY in renderer worker.
- Used this functions to implement the behavior when pausing.
- * Fixes NB#85894 incorrect duration reported
- * Fixes NB#93484 Playlist format other than wpl and ram shows its icon incorrectly in Playlists container
- * Fixes NB#94990 Gstreamer renderer gives seekable metadata TRUE for radio stream
-
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 19 Dec 2008 15:28:58 +0200
-
-midas-gstreamer-renderer (0.1.2008.51-1) unstable; urgency=low
-
- * (ha)xmas: hardwire ximagesink is removed
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 15 Dec 2008 12:55:59 +0200
-
-midas-gstreamer-renderer (0.1.2008.51) unstable; urgency=low
-
- * (ha)xmas: hardwire ximagesink temporarily
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 12 Dec 2008 14:57:37 +0200
-
-midas-gstreamer-renderer (0.1.2008.50) unstable; urgency=low
-
- * Added get_last_index method the the mock playlist in renderer
- tests.
- * Added new test cases for various use cases.
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 05 Dec 2008 13:29:06 +0200
-
-midas-gstreamer-renderer (0.1.2008.49) unstable; urgency=low
-
- * In development.
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 28 Nov 2008 14:35:35 +0200
-
-midas-gstreamer-renderer (0.1.2008.48) unstable; urgency=low
-
- * In renderer:
- --Renamed _get_graphic_file_path into _get_tmp_file_from_pool and
- changed to use the tmp files pool.
- --Replaced the calls to use _get_tmp_file_from_pool with the
- proper changes to parameters and return values.
- * Added resume operation to transitioning state in renderer that
- allows to resume in transitioning.
- * Added stop after pausing while transitioning to finish process in a better
- way in renderer tests.
- * Implemented HAL listener which stops renderer when usb cable is plugged
- in, and we are playing something from memory card
- * Changed do_next and do_prev to begin playback if pressing next
- or prev when going beyond the playlist limits in renderer.
- * Added mechanism to start/stop wrappers on package install/removal
- (ignoring scratchbox support for now). Uses DSME.
- Added an Xsession.post script.
- Updated affected components
- * Fixes: NB#92843 MidasRenderer ""playlist-changed"" and ""media-changed"" signals occur in random order when changing playlist
- * Fixes: NB#92238 Play state not preserved when next pressed in the end of the playlist.
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 21 Nov 2008 16:59:53 +0200
-
-midas-gstreamer-renderer (0.1.2008.47) unstable; urgency=low
-
- * Send error signal when handling playback errors.
- * Added conic network detection in renderer
- * Added error handing in renderer for CODEC_NOT_FOUND , seek error, network errors, DRM errors.
- * Fixes: NB#87297 Property of shuffle operation not reflected to the last item of playlist
- * Fixes: NB#87354 shuffle not applied to dynamically added clips
- * Fixes: NB#87667 Midas-playlist-daemon crashes with repeat mode 'on' & playing unsupported clip
- * Fixes: NB#91530 Media-changed signal comes everytime item is added to playlist
- * Fixes: NB#91566 glib criticals observed when audio playback is stopped
- * Fixes: NB#87841 Next and previous gives ""Index out of bounds error"" on last and first items
- * Fixes: NB#91893 local sink crashes when invalid playlist items are played
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 14 Nov 2008 12:30:41 +0200
-
-midas-gstreamer-renderer (0.1.2008.46) unstable; urgency=low
-
- * Fixes: NB#91061 gstreamer-gnomevfs pkgs missing.
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 07 Nov 2008 11:58:32 +0200
-
-midas-gstreamer-renderer (0.1.2008.45) unstable; urgency=low
-
- * Implemented move_to_last based on playlist get_last_index function
- * Implemented tag emission of renderer art in MidasGstreamerRenderer.
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 31 Oct 2008 14:14:16 +0200
-
-midas-gstreamer-renderer (0.1.2008.44) unstable; urgency=low
-
- * Added support to request the current frame
- * Added support for the property in the renderer and its storage on the worker.
- * added gdkpixbuf dependency.
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 24 Oct 2008 10:11:52 +0300
-
-midas-gstreamer-renderer (0.1.2008.43) unstable; urgency=low
-
- * Renaming local-sink->midas-gstreamer-renderer
- * support of playback on diablo
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 17 Oct 2008 15:03:14 +0300
-
-midas-gstreamer-renderer (0.1.2008.42) unstable; urgency=low
-
- * Fixes: NB#89265 unable to parse wpl playlist format files in local sink
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 10 Oct 2008 16:10:02 +0300
-
-midas-gstreamer-renderer (0.1.2008.40) unstable; urgency=low
-
- * Using playbin2.
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 29 Sep 2008 07:02:28 +0000
-
-midas-gstreamer-renderer (0.1.2008.39) unstable; urgency=low
-
- * Fixes: NB#87723 Play item pointer switches back to first item of playlist while repeat mode of playlist is not enabled
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Sun, 21 Sep 2008 18:35:06 +0300
-
-midas-gstreamer-renderer (0.1.2008.38) unstable; urgency=low
-
- * Unit tests fixed after the use_count API addition.
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 15 Sep 2008 08:11:12 +0300
-
-midas-gstreamer-renderer (0.1.2008.37) unstable; urgency=low
-
- * small face-lift (configure.ac, Makefile.am:s and build fixes)
- * Fixes: NB#86160 Media continues to play after deleting the playlist
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 08 Sep 2008 08:37:04 +0300
-
-midas-gstreamer-renderer (0.1.2008.36) unstable; urgency=low
-
- * Fixes: NB#87757 Seeking gives unknown seek mode as error in callback function
- * Fixes: NB#87414 Seek option is not enabled for mp3 format files
- * Fixes: NB#87463 playback is switched back to 20 seconds time stamp when the forward button is pressed
- * Fixes: NB#87524 Video full screen turns blank during pause playback state
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 01 Sep 2008 08:21:43 +0300
-
-midas-gstreamer-renderer (0.1.2008.35) unstable; urgency=low
-
- * In development.
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Sun, 24 Aug 2008 19:42:40 +0300
-
-midas-gstreamer-renderer (0.1.2008.34) unstable; urgency=low
-
- * More strict parameter checking by set_position().
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 15 Aug 2008 09:48:16 +0300
-
-midas-gstreamer-renderer (0.1.2008.33) unstable; urgency=low
-
- * Initial release.
- * Fixes: NB#85491 stop() in transitioning state
- * Fixes: NB#85894 incorrect duration reported
- * Fixes: NB#85481 Unable to seek attached mp3 file using MAFW api
- * Fixes: NB#85675 sink::metadata-changed signal reports the is-seekable key in integer
- * Fixes: NB#86692 local-sink doesn't emit buffering-info signals
- * Fixes: NB#85161 attempts to play media having unsupported format results in error message
- * Fixes: NB#85160 GLIB CRITICAL message trying to get the iradio-name metadata from gstreamer
- * Fixes: NB#85892 Pausing resets playback
- * Fixes: NB#85897 media always reported to be unseekable
- * Fixes: NB#86160 Media continues to play after deleting the playlist
- * Fixes: NB#86654 crash while playing from a playlist
- * Fixes: NB#85149 play(callback) is not invoked
- * Fixes: NB#85150 only the first item of the playlist is played
- * Fixes: NB#85498 sink should advance to next item if current is unplayable
- * Fixes: NB#86893 UPnP media content not playing
- * Fixes: NB#85472 play() starts last play_object()ed item again
- * Fixes: NB#85475 assign_playlist() starts playing
- * Fixes: NB#85479 misleading index in media-changed for play_object()
- * Fixes: NB#85628 crash if invoked without callback
- * Fixes: NB#87082 gstreamer criticals during playback
- * Fixes: NB#85489 critical warnings via assign_playlist(NULL)
- * Fixes: NB#87084 assign_playlist() critical warnings
- * Fixes: NB#86956 midas-dbus-wrapper dies when playback is attempted in mentioned scenario
-
- -- Zeeshan Ali <zeeshan.ali@nokia.com> Sun, 10 Aug 2008 19:52:39 +0300
+++ /dev/null
-Source: mafw-gst-subtitles-renderer
-Section: misc
-Priority: optional
-Maintainer: Roman Moravcik <roman.moravcik@gmail.com>
-XSBC-Original-Maintainer: Mika Tapojarvi <mika.tapojarvi@sse.fi>
-Build-Depends: debhelper (>= 4.0.0), libglib2.0-dev,
- libgstreamer0.10-dev (>= 0.10.20-0maemo3),
- libgstreamer-plugins-base0.10-dev (>= 0.10.20-0maemo5),
- libx11-dev, libosso-dev (>= 2.0), libmafw0-dev (>= 0.1),
- checkmore, gstreamer0.10-plugins-base,
- gstreamer0.10-plugins-good,
- libhal-dev, libtotem-plparser-dev, libpulse-dev (>= 0.9.15-1),
- libgconf2-dev, libosso-gnomevfs2-dev, mce-dev,
- libdbus-1-dev, hildon-control-panel-dev
-Standards-Version: 3.7.2
-Homepage: http://mafwsubrenderer.garage.maemo.org/
-Vcs-Browser: https://garage.maemo.org/plugins/ggit/browse.php/?p=mafwsubrenderer
-Vcs-Git: https://vcs.maemo.org/git/mafwsubrenderer
-
-Package: mafw-gst-subtitles-renderer
-Section: libs
-Architecture: any
-Depends: gconf2, ${shlibs:Depends}, ${misc:Depends}, gstreamer0.10-plugins-base-subtitles (>= 0.10.25-0maemo14+0m5-1)
-Replaces: mafw-gst-renderer
-Description: MAFW gst renderer plugin with subtitles support
- Renderer plugin for MAFW-gst
-
-Package: mafw-gst-subtitles-renderer-dbg
-Section: devel
-Architecture: any
-Priority: extra
-Depends: mafw-gst-subtitles-renderer (= ${binary:Version})
-Description: debug symbols for mafw-gst-subtitles-renderer
- MAFW-gst renderer debug symbols
-
-Package: mafw-gst-subtitles-applet
-Section: user/multimedia
-Architecture: any
-Depends: gconf2, ${shlibs:Depends}, ${misc:Depends}, mafw-gst-subtitles-renderer (= ${binary:Version})
-Description: External subtitles support for Media Player
- Subtitles font and encoding can be change via 'Settings: Subtitles'
- control panel applet.
-XB-Maemo-Display-Name: Subtitles Support
-XSBC-Bugtracker: https://garage.maemo.org/tracker/?func=add&group_id=1248&atid=4688
-XB-Maemo-Icon-26:
- iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0
- d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA9JJREFUeNrsWblOI0EQbVvm
- FodkIWRDQGAMERIgyxI5IcT+ATbYdEnZYGM23WD5CiDjA5AAOUKYQxY35jK2
- AZv72Hmt7Va7d46eY4UtTUkjV09NddfrquqjHPj4+CD1TEFS5+QD8AH4AHwA
- PgBXFJJfBAKB8Orq6o9YLPa1lgzNZrO/ksnkd23jvTYFoFH4+fk59P7+XlMz
- DZtgm/ZYAiCzs7Okvb2d8vPz8/z90tISWVxc5O2ZmRkyODhI+Z2dHTI3N6ck
- m5qaIpOTk7w9PT3NeehAlxH0oH93d6cWQqDNzU3S0NBAedETp6enJJ1O8/bt
- 7S2Xg1eVjY2NVfUryuQxYTzkLy8v6gBEent70+2YtZncqUwmHC5FmdVh0xKA
- OLjcGWRMrmekkQz9GOWYLLMCEJA/0Fah+PLy8reBgYEvn5m0CJn7+3skL23v
- 7e39TqVSPzV7dy09cHBwQFTuCb29vaSlpYXyDw8PNEfc0uvrK+np6eGGb2xs
- 0Bw6Pz9XD6FKpWKY9fIsNTY2cl5Fx4iurq7IyckJXf3YCggqFoskn8+TQqGg
- DsAsRuUEZ9+JvJ3ZhuGY3aenJ/qutbWVvpfHMOrbEIBKCIlAVXWY4TD67Oys
- yli9FYoZbwuAmYLsATaYigcwy8fHxzQcZMNFcKIMvFnfrjwgL5VGOjD86OiI
- XF5eKvUpAnDkAa8A3NzcUMPxq0qYbU9yQCWEZACMv7i4oLNtx/BP84B4XEBi
- Hh4eksfHR8fLqZ4H/msOYLBSqURDZWtry/VGJi4MYggZ2eM4hGA4wgQ7Jr7F
- rHtxh/AkhMwQw1AcNRAuw8PDpKuriwPyAoBnSSwDwDEBWz02H73BZNd76QFH
- OcAUcBbZ39+nce52I3OTA7YB4GSJXbNcLpvmAZutmgqhlZUV0tnZaWswrzzg
- SRL39/eT7u5uy8Gampr4YODj8bj7Ok8oVAWgr6+Pn1qVAWSzWX5uSSQSVZf6
- XC7H20NDQ/zsjiTf3t5WkkWjUXoZYrS+vs556ECXkXYTo/q41CgDwC2IVSVG
- Rkb4e+SEWEHAzYndyJDsa2trSjJUJSBnJMoikQiJxWK8nclk6MrnSVVC71Lv
- pCohVx7MxrRdWtRbaYzKKnISq8rkRJXBiTJHZZXx8fGqHdYouTs6Orgc/MTE
- hJKsra2tql9RhtAVZaOjozR8sA8tLCyoAYDx4XD4HwDNzc300fNQMBjkOnZk
- tBhrIgN42x7QVoycppiupeKutgrllAtbWCi0J05qi1DQSqsUtq7/frxLao9K
- lh6oN/L/I/MB+ADqnP4IMABJCQV+48xZ9wAAAABJRU5ErkJggg==
- ====
+++ /dev/null
-Copyright (C) 2007, 2008, 2009 Nokia Corporation. All rights reserved.
-
-Contact: Visa Smolander <visa.smolander@nokia.com>
-
-
-
+++ /dev/null
-#!/bin/sh
-
-if test -x /usr/sbin/dsmetool; then
- sudo /usr/bin/mafw.sh start mafw-gst-renderer -7
-fi
+++ /dev/null
-/usr/lib/hildon-control-panel/libcpmpsubtitles.so
-/usr/share/applications/hildon-control-panel/cpmpsubtitles.desktop
-/usr/share/locale/*
\ No newline at end of file
+++ /dev/null
-usr/lib/mafw-plugin
+++ /dev/null
-@plugindir@/*.so
+++ /dev/null
-#!/bin/sh
-
-#DEBHELPER#
-
-# purge old installed startup script
-if [ -f /etc/X11/Xsession.post/31mafw-gst-subtitles-renderer ]; then
- rm -f /etc/X11/Xsession.post/31mafw-gst-subtitles-renderer
-fi
-
-/usr/bin/mafw.sh start mafw-gst-renderer -7
-
-exit 0
+++ /dev/null
-#!/bin/sh
-
-#DEBHELPER#
-
-case "$1" in
- remove)
- # restore original mafw-gst-renderer on package removal
- if [ -f /usr/lib/mafw-plugin/mafw-gst-renderer.so.removed ]; then
- mv -f /usr/lib/mafw-plugin/mafw-gst-renderer.so.removed /usr/lib/mafw-plugin/mafw-gst-renderer.so
- fi
- ;;
- abort-upgrade|abort-remove|abort-deconfigure)
- ;;
- *)
- exit 0
-esac
-
-/usr/bin/mafw.sh start mafw-gst-renderer -7
-
-exit 0
+++ /dev/null
-#!/bin/sh
-
-#DEBHELPER#
-
-# create backup of original mafw-gst-renderer.so if it not exists
-if [ ! -f /usr/lib/mafw-plugin/mafw-gst-renderer.so.removed ]; then
- /usr/bin/mafw.sh stop mafw-gst-renderer
- mv -f /usr/lib/mafw-plugin/mafw-gst-renderer.so /usr/lib/mafw-plugin/mafw-gst-renderer.so.removed
-fi
-
-exit 0
+++ /dev/null
-#!/bin/sh
-
-#DEBHELPER#
-
-/usr/bin/mafw.sh stop mafw-gst-renderer
-
-exit 0
+++ /dev/null
-#!/usr/bin/make -f
-# -*- makefile -*-
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-# These are used for cross-compiling and for saving the configure script
-# from having to guess our platform (since we know it already)
-DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
-DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
-
-CFLAGS = -Wall -g
-
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
- CFLAGS += -O0
-else
- CFLAGS += -O2
-endif
-
-ifneq (,$(findstring thumb,$(DEB_BUILD_OPTIONS)))
- CFLAGS += -mthumb
-endif
-
-ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
- CFLAGS += -O0 -ggdb3 -finstrument-functions
-endif
-
-ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
- INSTALL_PROGRAM += -s
-endif
-maybe_coverage := $(if $(filter lcov,$(DEB_BUILD_OPTIONS)),--enable-coverage,)
-
-configure-stamp:
- dh_testdir
- CFLAGS="$(CFLAGS)" ./autogen.sh \
- --host=$(DEB_HOST_GNU_TYPE) \
- --build=$(DEB_BUILD_GNU_TYPE) \
- --disable-dependency-tracking \
- --prefix=/usr \
- $(maybe_coverage)
- touch configure-stamp
-
-build: build-stamp
-build-stamp: configure-stamp
- dh_testdir
- $(MAKE)
-ifeq ($(findstring nocheck,$(DEB_BUILD_OPTIONS)),)
- $(MAKE) check
-endif
- touch build-stamp
-
-clean:
- dh_testdir
- dh_testroot
- rm -f build-stamp configure-stamp
- [ ! -f Makefile ] || $(MAKE) distclean
- dh_clean
-
-install: build
- dh_testdir
- dh_testroot
- dh_clean -k
- dh_installdirs
- $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
-
-binary-indep: build install
-
-binary-arch: build install
- dh_testdir
- dh_testroot
- dh_installchangelogs ChangeLog
- dh_installdocs
- dh_install --sourcedir=debian/tmp -v
- dh_link
- dh_strip --dbg-package=mafw-gst-subtitles-renderer
- dh_compress
- dh_fixperms
- dh_installdeb
- dh_shlibdeps
- dh_gencontrol
- dh_md5sums
- dh_builddeb
-
-binary: binary-indep binary-arch
-
-distcheck: build
- dh_testdir
- $(MAKE) distcheck
-
-vg:
- dh_testdir
- $(MAKE) -C "$(CURDIR)/tests" vg
-
-
-.PHONY: build clean binary-indep binary-arch binary install distcheck vg
+++ /dev/null
-#
-# Makefile.am for MAFW gst renderer library.
-#
-# Author: Zeeshan Ali <zeeshan.ali@nokia.com>
-#
-# Copyright (C) 2007, 2008, 2009 Nokia. All rights reserved.
-
-plugin_LTLIBRARIES = mafw-gst-renderer.la
-
-BUILT_SOURCES = mafw-gst-renderer-marshal.c \
- mafw-gst-renderer-marshal.h
-
-mafw_gst_renderer_la_SOURCES = $(BUILT_SOURCES) \
- keypad.c keypad.h \
- blanking.c blanking.h \
- mafw-gst-renderer.c mafw-gst-renderer.h \
- mafw-gst-renderer-utils.c mafw-gst-renderer-utils.h \
- mafw-gst-renderer-worker.c mafw-gst-renderer-worker.h \
- mafw-gst-renderer-worker-volume.c mafw-gst-renderer-worker-volume.h \
- mafw-gst-renderer-state.c mafw-gst-renderer-state.h \
- mafw-gst-renderer-state-playing.c mafw-gst-renderer-state-playing.h \
- mafw-gst-renderer-state-paused.c mafw-gst-renderer-state-paused.h \
- mafw-gst-renderer-state-stopped.c mafw-gst-renderer-state-stopped.h \
- mafw-gst-renderer-state-transitioning.c mafw-gst-renderer-state-transitioning.h \
- mafw-playlist-iterator.c mafw-playlist-iterator.h
-
-mafw_gst_renderer_la_CPPFLAGS = $(DEPS_CFLAGS) $(VOLUME_CFLAGS) \
- -DPREFIX=\"$(prefix)\" $(_CFLAGS)
-mafw_gst_renderer_la_LDFLAGS = -avoid-version -module $(_LDFLAGS)
-mafw_gst_renderer_la_LIBADD = $(DEPS_LIBS) $(VOLUME_LIBS) \
- -lgstinterfaces-0.10 -lgstpbutils-0.10
-
-if HAVE_GDKPIXBUF
-mafw_gst_renderer_la_SOURCES += gstscreenshot.c gstscreenshot.h
-mafw_gst_renderer_la_CPPFLAGS += $(GDKPIXBUF_CFLAGS)
-mafw_gst_renderer_la_LIBADD += $(GDKPIXBUF_LIBS)
-endif
-
-if HAVE_CONIC
-mafw_gst_renderer_la_CPPFLAGS += $(CONIC_CFLAGS)
-mafw_gst_renderer_la_LIBADD += $(CONIC_LIBS)
-endif
-
-mafw-gst-renderer-marshal.c: mafw-gst-renderer-marshal.list
- ( \
- echo '#include "mafw-gst-renderer-marshal.h"'; \
- $(GLIB_GENMARSHAL) --prefix=mafw_gst_renderer_marshal --body $^ \
- ) > $@
-
-mafw-gst-renderer-marshal.h: mafw-gst-renderer-marshal.list
- $(GLIB_GENMARSHAL) --prefix=mafw_gst_renderer_marshal --header \
- $^ > $@
-
-EXTRA_DIST = mafw-gst-renderer-marshal.list
-CLEANFILES = *.gcno *.gcda
-MAINTAINERCLEANFILES = Makefile.in *.loT
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <libosso.h>
-#include "blanking.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-blanking"
-
-/* In seconds */
-#define VIDEO_BLANKING_TIMER_INTERVAL 45
-
-static guint blanking_timeout_id = 0;
-static osso_context_t *osso_ctx = NULL;
-static gboolean can_control_blanking = TRUE;
-static gboolean is_blanking_prohibited = FALSE;
-
-static void remove_blanking_timeout(void)
-{
- if (blanking_timeout_id) {
- g_source_remove(blanking_timeout_id);
- blanking_timeout_id = 0;
- }
-}
-
-/*
- * Re-enables screen blanking.
- */
-void blanking_allow(void)
-{
- is_blanking_prohibited = FALSE;
- remove_blanking_timeout();
-}
-
-static gboolean no_blanking_timeout(void)
-{
- /* Stop trying if it fails. */
- return osso_display_blanking_pause(osso_ctx) == OSSO_OK;
-}
-
-/*
- * Adds a timeout to periodically disable screen blanking.
- */
-void blanking_prohibit(void)
-{
- is_blanking_prohibited = TRUE;
- if ((!osso_ctx) || (!can_control_blanking))
- return;
- osso_display_state_on(osso_ctx);
- osso_display_blanking_pause(osso_ctx);
- if (blanking_timeout_id == 0) {
- blanking_timeout_id =
- g_timeout_add_seconds(VIDEO_BLANKING_TIMER_INTERVAL,
- (gpointer)no_blanking_timeout,
- NULL);
- }
-}
-
-void blanking_init(void)
-{
- /* It's enough to initialize it once for a process. */
- if (osso_ctx)
- return;
- osso_ctx = osso_initialize(PACKAGE, VERSION, 0, NULL);
- if (!osso_ctx)
- g_warning("osso_initialize failed, screen may go black");
- is_blanking_prohibited = FALSE;
- /* Default policy is to allow user to control blanking */
- blanking_control(TRUE);
-}
-
-void blanking_deinit(void)
-{
- if (!osso_ctx)
- return;
- blanking_control(FALSE);
- osso_deinitialize(osso_ctx);
- osso_ctx = NULL;
-}
-
-void blanking_control(gboolean activate)
-{
- can_control_blanking = activate;
- if (!can_control_blanking) {
- remove_blanking_timeout();
- } else {
- /* Restore the last state */
- if (is_blanking_prohibited) {
- blanking_prohibit();
- } else {
- blanking_allow();
- }
- }
-}
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef BLANKING_H
-#define BLANKING_H
-
-G_BEGIN_DECLS
-
-void blanking_init(void);
-void blanking_deinit(void);
-void blanking_allow(void);
-void blanking_prohibit(void);
-void blanking_control(gboolean activate);
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-/* Small helper element for format conversion
- * (c) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
- * Portion Copyright © 2009 Nokia Corporation and/or its
- * subsidiary(-ies).* All rights reserved. *
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <string.h>
-
-#include "gstscreenshot.h"
-
-typedef struct {
- GstBuffer *result;
- GstElement *src;
- GstElement *sink;
- GstElement *pipeline;
- BvwFrameConvCb cb;
- gpointer cb_data;
-} GstScreenshotData;
-
-/* GST_DEBUG_CATEGORY_EXTERN (_totem_gst_debug_cat); */
-/* #define GST_CAT_DEFAULT _totem_gst_debug_cat */
-
-static void feed_fakesrc(GstElement *src, GstBuffer *buf, GstPad *pad,
- gpointer data)
-{
- GstBuffer *in_buf = GST_BUFFER(data);
-
- g_assert(GST_BUFFER_SIZE(buf) >= GST_BUFFER_SIZE(in_buf));
- g_assert(!GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_READONLY));
-
- gst_buffer_set_caps(buf, GST_BUFFER_CAPS(in_buf));
-
- memcpy(GST_BUFFER_DATA(buf), GST_BUFFER_DATA(in_buf),
- GST_BUFFER_SIZE(in_buf));
-
- GST_BUFFER_SIZE(buf) = GST_BUFFER_SIZE(in_buf);
-
- GST_DEBUG("feeding buffer %p, size %u, caps %" GST_PTR_FORMAT,
- buf, GST_BUFFER_SIZE(buf), GST_BUFFER_CAPS(buf));
-
- gst_buffer_unref(in_buf);
-}
-
-static void save_result(GstElement *sink, GstBuffer *buf, GstPad *pad,
- gpointer data)
-{
- GstScreenshotData *gsd = data;
-
- gsd->result = gst_buffer_ref(buf);
-
- GST_DEBUG("received converted buffer %p with caps %" GST_PTR_FORMAT,
- gsd->result, GST_BUFFER_CAPS(gsd->result));
-}
-
-static gboolean create_element(const gchar *factory_name, GstElement **element,
- GError **err)
-{
- *element = gst_element_factory_make(factory_name, NULL);
- if (*element)
- return TRUE;
-
- if (err && *err == NULL) {
- *err = g_error_new(
- GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN,
- "cannot create element '%s' - please check your "
- "GStreamer installation", factory_name);
- }
-
- return FALSE;
-}
-
-static gboolean finalize_process(GstScreenshotData *gsd)
-{
- g_signal_handlers_disconnect_matched(gsd->sink, (GSignalMatchType)
- G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
- save_result, NULL);
- g_signal_handlers_disconnect_matched(gsd->src, (GSignalMatchType)
- G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
- feed_fakesrc, NULL);
- gst_element_set_state(gsd->pipeline, GST_STATE_NULL);
-
- g_free(gsd);
-
- return FALSE;
-}
-
-static gboolean async_bus_handler(GstBus *bus, GstMessage *msg,
- gpointer data)
-{
- GstScreenshotData *gsd = data;
- gboolean keep_watch = TRUE;
-
- switch (GST_MESSAGE_TYPE(msg)) {
- case GST_MESSAGE_EOS: {
- if (gsd->result != NULL) {
- GST_DEBUG("conversion successful: result = %p",
- gsd->result);
- } else {
- GST_WARNING("EOS but no result frame?!");
- }
- gsd->cb(gsd->result, gsd->cb_data);
- keep_watch = finalize_process(gsd);
- break;
- }
- case GST_MESSAGE_ERROR: {
- gchar *dbg = NULL;
- GError *error = NULL;
-
- gst_message_parse_error(msg, &error, &dbg);
- if (error != NULL) {
- g_warning("Could not take screenshot: %s",
- error->message);
- GST_DEBUG("%s [debug: %s]", error->message,
- GST_STR_NULL(dbg));
- g_error_free(error);
- } else {
- g_warning("Could not take screenshot(and "
- "NULL error!)");
- }
- g_free(dbg);
- gsd->result = NULL;
- gsd->cb(gsd->result, gsd->cb_data);
- keep_watch = finalize_process(gsd);
- break;
- }
- default:
- break;
- }
-
- return keep_watch;
-}
-
-/* takes ownership of the input buffer */
-gboolean bvw_frame_conv_convert(GstBuffer *buf, GstCaps *to_caps,
- BvwFrameConvCb cb, gpointer cb_data)
-{
- static GstElement *src = NULL, *sink = NULL, *pipeline = NULL,
- *filter1 = NULL, *filter2 = NULL;
- static GstBus *bus;
- GError *error = NULL;
- GstCaps *to_caps_no_par;
- GstScreenshotData *gsd;
-
- g_return_val_if_fail(GST_BUFFER_CAPS(buf) != NULL, FALSE);
- g_return_val_if_fail(cb != NULL, FALSE);
-
- if (pipeline == NULL) {
- GstElement *csp, *vscale;
-
- pipeline = gst_pipeline_new("screenshot-pipeline");
- if(pipeline == NULL) {
- g_warning("Could not take screenshot: "
- "no pipeline (unknown error)");
- return FALSE;
- }
-
- /* videoscale is here to correct for the
- * pixel-aspect-ratio for us */
- GST_DEBUG("creating elements");
- if(!create_element("fakesrc", &src, &error) ||
- !create_element("ffmpegcolorspace", &csp, &error) ||
- !create_element("videoscale", &vscale, &error) ||
- !create_element("capsfilter", &filter1, &error) ||
- !create_element("capsfilter", &filter2, &error) ||
- !create_element("fakesink", &sink, &error)) {
- g_warning("Could not take screenshot: %s",
- error->message);
- g_error_free(error);
- return FALSE;
- }
-
- GST_DEBUG("adding elements");
- gst_bin_add_many(GST_BIN(pipeline), src, csp, filter1, vscale,
- filter2, sink, NULL);
-
- g_object_set(sink, "preroll-queue-len", 1,
- "signal-handoffs", TRUE, NULL);
-
- /* set to 'fixed' sizetype */
- g_object_set(src, "sizetype", 2, "num-buffers", 1,
- "signal-handoffs", TRUE, NULL);
-
- /* FIXME: linking is still way too expensive, profile
- * this properly */
- GST_DEBUG("linking src->csp");
- if(!gst_element_link_pads(src, "src", csp, "sink"))
- return FALSE;
-
- GST_DEBUG("linking csp->filter1");
- if(!gst_element_link_pads(csp, "src", filter1, "sink"))
- return FALSE;
-
- GST_DEBUG("linking filter1->vscale");
- if(!gst_element_link_pads(filter1, "src", vscale, "sink"))
- return FALSE;
-
- GST_DEBUG("linking vscale->capsfilter");
- if(!gst_element_link_pads(vscale, "src", filter2, "sink"))
- return FALSE;
-
- GST_DEBUG("linking capsfilter->sink");
- if(!gst_element_link_pads(filter2, "src", sink, "sink"))
- return FALSE;
-
- bus = gst_element_get_bus(pipeline);
- }
-
- /* adding this superfluous capsfilter makes linking cheaper */
- to_caps_no_par = gst_caps_copy(to_caps);
- gst_structure_remove_field(gst_caps_get_structure(to_caps_no_par, 0),
- "pixel-aspect-ratio");
- g_object_set(filter1, "caps", to_caps_no_par, NULL);
- gst_caps_unref(to_caps_no_par);
-
- g_object_set(filter2, "caps", to_caps, NULL);
- gst_caps_unref(to_caps);
-
- gsd = g_new0(GstScreenshotData, 1);
-
- gsd->src = src;
- gsd->sink = sink;
- gsd->pipeline = pipeline;
- gsd->cb = cb;
- gsd->cb_data = cb_data;
-
- g_signal_connect(sink, "handoff", G_CALLBACK(save_result), gsd);
-
- g_signal_connect(src, "handoff", G_CALLBACK(feed_fakesrc), buf);
-
- gst_bus_add_watch(bus, async_bus_handler, gsd);
-
- /* set to 'fixed' sizetype */
- g_object_set(src, "sizemax", GST_BUFFER_SIZE(buf), NULL);
-
- GST_DEBUG("running conversion pipeline");
- gst_element_set_state(pipeline, GST_STATE_PLAYING);
-
- return TRUE;
-}
+++ /dev/null
-/* Small helper element for format conversion
- * (c) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
- * Portion Copyright © 2009 Nokia Corporation and/or its
- * subsidiary(-ies).* All rights reserved. *
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __BVW_FRAME_CONV_H__
-#define __BVW_FRAME_CONV_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-typedef void (*BvwFrameConvCb)(GstBuffer *result, gpointer user_data);
-
-gboolean bvw_frame_conv_convert (GstBuffer *buf, GstCaps *to,
- BvwFrameConvCb cb, gpointer cb_data);
-
-G_END_DECLS
-
-#endif /* __BVW_FRAME_CONV_H__ */
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <glib.h>
-#include <mce/dbus-names.h>
-#include <dbus/dbus.h>
-#include "keypad.h"
-
-
-#define KEYPAD_TIMER_INTERVAL 50
-
-static guint toutid;
-
-void keypadlocking_allow(void)
-{
- if (toutid)
- {
- g_source_remove(toutid);
- toutid = 0;
- }
-}
-
-static gboolean no_keylock_timeout(gpointer udata)
-{
- static DBusMessage *msg = NULL;
- static DBusConnection *sysbus = NULL;
-
- if (!sysbus)
- {
- DBusError err;
-
- dbus_error_init(&err);
- sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
- g_assert(sysbus);
- g_assert(!dbus_error_is_set(&err));
- }
- if (!msg)
- {
- msg = dbus_message_new_method_call(MCE_SERVICE,
- MCE_REQUEST_PATH, MCE_REQUEST_IF,
- MCE_PREVENT_KEYPAD_OFF_REQ);
- g_assert(msg);
- }
- g_assert(dbus_connection_send(sysbus, msg,NULL));
- dbus_connection_flush(sysbus);
- return TRUE;
-}
-
-void keypadlocking_prohibit(void)
-{
- if (!toutid)
- {
- toutid = g_timeout_add_seconds(KEYPAD_TIMER_INTERVAL,
- no_keylock_timeout,
- NULL);
- no_keylock_timeout(NULL);
- }
-}
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef KEYPAD_H
-#define KEYPAD_H
-
-G_BEGIN_DECLS
-
-void keypadlocking_prohibit(void);
-void keypadlocking_allow(void);
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-#include "mafw-gst-renderer-marshal.h"
-
-#include <glib-object.h>
-
-
-#ifdef G_ENABLE_DEBUG
-#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
-#define g_marshal_value_peek_char(v) g_value_get_char (v)
-#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
-#define g_marshal_value_peek_int(v) g_value_get_int (v)
-#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
-#define g_marshal_value_peek_long(v) g_value_get_long (v)
-#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
-#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
-#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
-#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
-#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
-#define g_marshal_value_peek_float(v) g_value_get_float (v)
-#define g_marshal_value_peek_double(v) g_value_get_double (v)
-#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
-#define g_marshal_value_peek_param(v) g_value_get_param (v)
-#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
-#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
-#define g_marshal_value_peek_object(v) g_value_get_object (v)
-#else /* !G_ENABLE_DEBUG */
-/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
- * Do not access GValues directly in your code. Instead, use the
- * g_value_get_*() functions
- */
-#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
-#define g_marshal_value_peek_char(v) (v)->data[0].v_int
-#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_int(v) (v)->data[0].v_int
-#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_long(v) (v)->data[0].v_long
-#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
-#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
-#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
-#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
-#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
-#define g_marshal_value_peek_float(v) (v)->data[0].v_float
-#define g_marshal_value_peek_double(v) (v)->data[0].v_double
-#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
-#endif /* !G_ENABLE_DEBUG */
-
-
-/* VOID:BOOLEAN,UINT,INT,STRING (mafw-gst-renderer-marshal.list:2) */
-void
-mafw_gst_renderer_marshal_VOID__BOOLEAN_UINT_INT_STRING (GClosure *closure,
- GValue *return_value G_GNUC_UNUSED,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint G_GNUC_UNUSED,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__BOOLEAN_UINT_INT_STRING) (gpointer data1,
- gboolean arg_1,
- guint arg_2,
- gint arg_3,
- gpointer arg_4,
- gpointer data2);
- register GMarshalFunc_VOID__BOOLEAN_UINT_INT_STRING callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 5);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__BOOLEAN_UINT_INT_STRING) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_boolean (param_values + 1),
- g_marshal_value_peek_uint (param_values + 2),
- g_marshal_value_peek_int (param_values + 3),
- g_marshal_value_peek_string (param_values + 4),
- data2);
-}
-
+++ /dev/null
-
-#ifndef __mafw_gst_renderer_marshal_MARSHAL_H__
-#define __mafw_gst_renderer_marshal_MARSHAL_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/* VOID:BOOLEAN,UINT,INT,STRING (mafw-gst-renderer-marshal.list:2) */
-extern void mafw_gst_renderer_marshal_VOID__BOOLEAN_UINT_INT_STRING (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-G_END_DECLS
-
-#endif /* __mafw_gst_renderer_marshal_MARSHAL_H__ */
-
+++ /dev/null
-# MafwPlaylistIterator::playlist-changed(clip_changed, domain, code, message)
-VOID: BOOLEAN, UINT, INT, STRING
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "mafw-gst-renderer-state-paused.h"
-#include "mafw-gst-renderer-utils.h"
-#include <libmafw/mafw.h>
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-state-paused"
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-static void _do_play(MafwGstRendererState *self, GError **error);
-static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
- GError **error);
-static void _do_stop(MafwGstRendererState *self, GError **error);
-static void _do_resume(MafwGstRendererState *self, GError **error);
-static void _do_set_position(MafwGstRendererState *self,
- MafwRendererSeekMode mode, gint seconds,
- GError **error);
-static void _do_get_position(MafwGstRendererState *self,
- gint *seconds,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-static void _do_next(MafwGstRendererState *self, GError **error);
-static void _do_previous(MafwGstRendererState *self, GError **error);
-static void _do_goto_index(MafwGstRendererState *self, guint index,
- GError **error);
-/*----------------------------------------------------------------------------
- Notification metatada
- ----------------------------------------------------------------------------*/
-
-static void _notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Notification worker
- ----------------------------------------------------------------------------*/
-
-static void _notify_play(MafwGstRendererState *self, GError **error);
-static void _notify_seek(MafwGstRendererState *self, GError **error);
-static void _notify_buffer_status(MafwGstRendererState *self, gdouble percent,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Playlist editing signals
- ----------------------------------------------------------------------------*/
-
-static void _playlist_contents_changed(MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Property methods
- ----------------------------------------------------------------------------*/
-
-static GValue* _get_property_value(MafwGstRendererState *self,
- const gchar *name);
-
-/*----------------------------------------------------------------------------
- Memory card event handlers
- ----------------------------------------------------------------------------*/
-
-static void _handle_pre_unmount(MafwGstRendererState *self,
- const gchar *mount_point);
-
-/*----------------------------------------------------------------------------
- GObject initialization
- ----------------------------------------------------------------------------*/
-
-G_DEFINE_TYPE(MafwGstRendererStatePaused, mafw_gst_renderer_state_paused,
- MAFW_TYPE_GST_RENDERER_STATE);
-
-static void mafw_gst_renderer_state_paused_init(MafwGstRendererStatePaused *self)
-{
-}
-
-static void mafw_gst_renderer_state_paused_class_init(
- MafwGstRendererStatePausedClass *klass)
-{
- MafwGstRendererStateClass *state_class;
-
- state_class = MAFW_GST_RENDERER_STATE_CLASS(klass);
- g_return_if_fail(state_class != NULL);
-
- state_class->name = g_strdup("Paused");
-
- /* Playback */
-
- state_class->play = _do_play;
- state_class->play_object = _do_play_object;
- state_class->stop = _do_stop;
- state_class->resume = _do_resume;
- state_class->set_position = _do_set_position;
- state_class->get_position = _do_get_position;
-
- /* Playlist */
-
- state_class->next = _do_next;
- state_class->previous = _do_previous;
- state_class->goto_index = _do_goto_index;
-
- /* Notification metadata */
-
- state_class->notify_metadata = _notify_metadata;
-
- /* Notification worker */
-
- state_class->notify_play = _notify_play;
- /* state_class->notify_pause is not allowed */
- state_class->notify_seek = _notify_seek;
- state_class->notify_buffer_status = _notify_buffer_status;
-
- /* Playlist editing signals */
-
- state_class->playlist_contents_changed =
- _playlist_contents_changed;
-
- /* Property methods */
-
- state_class->get_property_value = _get_property_value;
-
- /* Memory card event handlers */
-
- state_class->handle_pre_unmount = _handle_pre_unmount;
-}
-
-GObject *mafw_gst_renderer_state_paused_new(MafwGstRenderer *renderer)
-{
- MafwGstRendererState *state;
-
- state = MAFW_GST_RENDERER_STATE(
- g_object_new(MAFW_TYPE_GST_RENDERER_STATE_PAUSED, NULL));
- state->renderer = renderer;
-
- return G_OBJECT(state);
-}
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-static void _do_play(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
- mafw_gst_renderer_state_do_play(self, error);
-}
-
-static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
- GError **error)
-{
- MafwGstRendererPlaybackMode cur_mode, prev_mode;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
-
- self->renderer->worker->stay_paused = FALSE;
- prev_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
- mafw_gst_renderer_state_do_play_object(self, object_id, error);
- cur_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
-
- /* If this happens it means that we interrupted playlist playback
- so let's resume it when play_object is finished */
- if (cur_mode != prev_mode) {
- self->renderer->resume_playlist = TRUE;
- }
-}
-
-static void _do_stop(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
-
- self->renderer->worker->stay_paused = FALSE;
- /* Stop playback */
- mafw_gst_renderer_state_do_stop(self, error);
-}
-
-static void _do_resume(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
-
- MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
- self->renderer->worker->stay_paused = FALSE;
- mafw_gst_renderer_worker_resume(renderer->worker);
-
- /* Transition will be done after receiving notify_play */
-}
-
-static void _do_set_position(MafwGstRendererState *self,
- MafwRendererSeekMode mode, gint seconds,
- GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
- self->renderer->worker->stay_paused = TRUE;
- mafw_gst_renderer_state_do_set_position(self, mode, seconds, error);
-}
-
-static void _do_get_position(MafwGstRendererState *self,
- gint *seconds,
- GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
- mafw_gst_renderer_state_do_get_position(self, seconds, error);
-}
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-static void _do_next(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
- self->renderer->worker->stay_paused = TRUE;
- mafw_gst_renderer_state_do_next(self, error);
-}
-
-static void _do_previous(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
- self->renderer->worker->stay_paused = TRUE;
- mafw_gst_renderer_state_do_prev(self, error);
-}
-
-static void _do_goto_index(MafwGstRendererState *self, guint index,
- GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
- self->renderer->worker->stay_paused = TRUE;
- mafw_gst_renderer_state_do_goto_index(self, index, error);
-}
-
-
-/*----------------------------------------------------------------------------
- Notification metatada
- ----------------------------------------------------------------------------*/
-
-static void _notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error)
-{
- g_debug("running _notify_metadata...");
- /* Kindly Ignore this notification:
- probably a delayed (now useless) metadata resolution */
-}
-
-
-/*----------------------------------------------------------------------------
- Notification worker
- ----------------------------------------------------------------------------*/
-
-static void _notify_play(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
-
- MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- /* Change status to play */
- mafw_gst_renderer_set_state(renderer, Playing);
-}
-
-static void _notify_seek(MafwGstRendererState *self, GError **error)
-{
- mafw_gst_renderer_state_do_notify_seek(self, error);
-}
-
-static void _notify_buffer_status(MafwGstRendererState *self, gdouble percent,
- GError **error)
-{
- mafw_gst_renderer_state_do_notify_buffer_status (self, percent, error);
-}
-
-/*----------------------------------------------------------------------------
- Playlist editing signals
- ----------------------------------------------------------------------------*/
-
-static void _playlist_contents_changed(MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error)
-{
- MafwGstRendererPlaybackMode mode;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
-
- /* Play the new index only if we are not in standalone mode.
- Otherwise, when play_object finishes the new item will be
- played if that's been suggested with renderer->resume_playlist */
- mode = mafw_gst_renderer_get_playback_mode(self->renderer);
- if (clip_changed && mode == MAFW_GST_RENDERER_MODE_PLAYLIST) {
- self->renderer->worker->stay_paused = TRUE;
- mafw_gst_renderer_state_do_play(self, error);
- }
-}
-
-/*----------------------------------------------------------------------------
- Property methods
- ----------------------------------------------------------------------------*/
-
-GValue* _get_property_value(MafwGstRendererState *self, const gchar *name)
-{
- GValue *value = NULL;
-
- g_return_val_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self), value);
-
- if (!g_strcmp0(name, MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS)) {
- gboolean is_seekable =
- mafw_gst_renderer_worker_get_seekable(
- self->renderer->worker);
-
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_STRING);
- if (is_seekable) {
- g_value_set_string(value, "seek");
- } else {
- g_value_set_string(value, "");
- }
- }
-
- return value;
-}
-
-/*----------------------------------------------------------------------------
- Memory card event handlers
- ----------------------------------------------------------------------------*/
-
-static void _handle_pre_unmount(MafwGstRendererState *self,
- const gchar *mount_point)
-{
- gchar *mount_uri;
-
- /* If not playing anything, bail out */
- if (!self->renderer->media->uri) {
- return;
- }
-
- /* Check if mount point is URI or path, we need URI */
- if (!g_str_has_prefix(mount_point, "file://")) {
- mount_uri = g_filename_to_uri(mount_point, NULL, NULL);
- } else {
- mount_uri = g_strdup(mount_point);
- }
-
- /* Stop if playing from unmounted location */
- if (g_str_has_prefix(self->renderer->media->uri, mount_uri)) {
- g_debug("PAUSED-STATE: stopping to mount card");
- mafw_gst_renderer_stop(MAFW_RENDERER(self->renderer),
- NULL,
- NULL);
- }
-
- g_free(mount_uri);
-}
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef MAFW_GST_RENDERER_STATE_PAUSED_H
-#define MAFW_GST_RENDERER_STATE_PAUSED_H
-
-
-#include "mafw-gst-renderer.h"
-#include "mafw-gst-renderer-state.h"
-
-G_BEGIN_DECLS
-
-/*----------------------------------------------------------------------------
- GObject type conversion macros
- ----------------------------------------------------------------------------*/
-
-#define MAFW_TYPE_GST_RENDERER_STATE_PAUSED \
- (mafw_gst_renderer_state_paused_get_type())
-#define MAFW_GST_RENDERER_STATE_PAUSED(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_GST_RENDERER_STATE_PAUSED, \
- MafwGstRendererStatePaused))
-#define MAFW_IS_GST_RENDERER_STATE_PAUSED(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_GST_RENDERER_STATE_PAUSED))
-#define MAFW_GST_RENDERER_STATE_PAUSED_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_GST_RENDERER_STATE_PAUSED, \
- MafwGstRendererStatePaused))
-#define MAFW_GST_RENDERER_STATE_PAUSED_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_GST_RENDERER_STATE_PAUSED, \
- MafwGstRendererStatePausedClass))
-#define MAFW_IS_GST_RENDERER_STATE_PAUSED_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_GST_RENDERER_STATE_PAUSED))
-
-/*----------------------------------------------------------------------------
- Type definitions
- ----------------------------------------------------------------------------*/
-
-
-typedef struct _MafwGstRendererStatePaused MafwGstRendererStatePaused;
-typedef struct _MafwGstRendererStatePausedClass MafwGstRendererStatePausedClass;
-
-struct _MafwGstRendererStatePausedClass {
- MafwGstRendererStateClass parent_class;
-};
-
-struct _MafwGstRendererStatePaused {
- MafwGstRendererState parent;
-};
-
-GType mafw_gst_renderer_state_paused_get_type(void);
-
-GObject *mafw_gst_renderer_state_paused_new(MafwGstRenderer *renderer);
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "mafw-gst-renderer-state-playing.h"
-#include "mafw-gst-renderer-utils.h"
-#include <libmafw/mafw.h>
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-state-playing"
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-static void _do_play(MafwGstRendererState *self, GError **error);
-static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
- GError **error);
-static void _do_stop(MafwGstRendererState *self, GError **error);
-static void _do_pause(MafwGstRendererState *self, GError **error);
-static void _do_set_position(MafwGstRendererState *self,
- MafwRendererSeekMode mode, gint seconds,
- GError **error);
-static void _do_get_position(MafwGstRendererState *self,
- gint *seconds,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-static void _do_next(MafwGstRendererState *self, GError **error);
-static void _do_previous(MafwGstRendererState *self, GError **error);
-static void _do_goto_index(MafwGstRendererState *self, guint index,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Notification metatada
- ----------------------------------------------------------------------------*/
-
-static void _notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Notification worker
- ----------------------------------------------------------------------------*/
-
-static void _notify_play(MafwGstRendererState *self, GError **error);
-static void _notify_pause(MafwGstRendererState *self, GError **error);
-static void _notify_seek(MafwGstRendererState *self, GError **error);
-static void _notify_buffer_status(MafwGstRendererState *self, gdouble percent,
- GError **error);
-static void _notify_eos(MafwGstRendererState *self, GError **error);
-
-/*----------------------------------------------------------------------------
- Playlist editing signals
- ----------------------------------------------------------------------------*/
-
-static void _playlist_contents_changed(MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Property methods
- ----------------------------------------------------------------------------*/
-
-static GValue* _get_property_value(MafwGstRendererState *self,
- const gchar *name);
-
-/*----------------------------------------------------------------------------
- Memory card event handlers
- ----------------------------------------------------------------------------*/
-
-static void _handle_pre_unmount(MafwGstRendererState *self,
- const gchar *mount_point);
-
-/*----------------------------------------------------------------------------
- GObject initialization
- ----------------------------------------------------------------------------*/
-
-G_DEFINE_TYPE(MafwGstRendererStatePlaying, mafw_gst_renderer_state_playing,
- MAFW_TYPE_GST_RENDERER_STATE);
-
-static void mafw_gst_renderer_state_playing_init(MafwGstRendererStatePlaying *self)
-{
-}
-
-static void mafw_gst_renderer_state_playing_class_init(
- MafwGstRendererStatePlayingClass *klass)
-{
- MafwGstRendererStateClass *state_class;
-
- state_class = MAFW_GST_RENDERER_STATE_CLASS(klass);
- g_return_if_fail(state_class != NULL);
-
- state_class->name = g_strdup("Playing");
-
- /* Playback */
-
- state_class->play = _do_play;
- state_class->play_object = _do_play_object;
- state_class->stop = _do_stop;
- state_class->pause = _do_pause;
- /* state_class->resume is not allowed */
- state_class->set_position = _do_set_position;
- state_class->get_position = _do_get_position;
-
- /* Playlist */
-
- state_class->next = _do_next;
- state_class->previous = _do_previous;
- state_class->goto_index = _do_goto_index;
-
- /* Notification metadata */
-
- state_class->notify_metadata = _notify_metadata;
-
- /* Notification worker */
-
- state_class->notify_play = _notify_play;
- state_class->notify_pause = _notify_pause;
- state_class->notify_seek = _notify_seek;
- state_class->notify_buffer_status = _notify_buffer_status;
- state_class->notify_eos = _notify_eos;
-
- /* Playlist editing signals */
-
- state_class->playlist_contents_changed =
- _playlist_contents_changed;
-
- /* Property methods */
-
- state_class->get_property_value = _get_property_value;
-
- /* Memory card event handlers */
-
- state_class->handle_pre_unmount = _handle_pre_unmount;
-}
-
-GObject *mafw_gst_renderer_state_playing_new(MafwGstRenderer *renderer)
-{
- MafwGstRendererState *state;
-
- state = MAFW_GST_RENDERER_STATE(
- g_object_new(MAFW_TYPE_GST_RENDERER_STATE_PLAYING, NULL));
- state->renderer = renderer;
-
- return G_OBJECT(state);
-}
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-static void _do_play(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
- mafw_gst_renderer_state_do_play(self, error);
-}
-
-static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
- GError **error)
-{
- MafwGstRendererPlaybackMode cur_mode, prev_mode;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
-
- prev_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
- mafw_gst_renderer_state_do_play_object(self, object_id, error);
- cur_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
-
- /* If this happens it means that we interrupted playlist playback
- so let's resume it when play_object is finished */
- if (cur_mode != prev_mode) {
- self->renderer->resume_playlist = TRUE;
- }
-}
-
-static void _do_stop(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
-
- /* Stop playback */
- mafw_gst_renderer_state_do_stop(self, error);
-}
-
-static void _do_pause(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
-
- MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
- mafw_gst_renderer_worker_pause(renderer->worker);
-
- /* Transition will be done when receiving pause
- * notification */
-}
-
-static void _do_set_position(MafwGstRendererState *self,
- MafwRendererSeekMode mode, gint seconds,
- GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
- mafw_gst_renderer_state_do_set_position(self, mode, seconds, error);
-}
-
-static void _do_get_position(MafwGstRendererState *self,
- gint *seconds,
- GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
- mafw_gst_renderer_state_do_get_position(self, seconds, error);
-}
-
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-static void _do_next(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
- mafw_gst_renderer_state_do_next(self, error);
-}
-
-static void _do_previous(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
- mafw_gst_renderer_state_do_prev(self, error);
-}
-
-static void _do_goto_index(MafwGstRendererState *self, guint index,
- GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
- mafw_gst_renderer_state_do_goto_index(self, index, error);
-}
-
-
-/*----------------------------------------------------------------------------
- Notification metatada
- ----------------------------------------------------------------------------*/
-
-static void _notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error)
-{
- g_debug("running _notify_metadata...");
- /* Kindly Ignore this notification:
- probably a delayed (now useless) metadata resolution */
-}
-
-
-/*----------------------------------------------------------------------------
- Notification worker
- ----------------------------------------------------------------------------*/
-
-static void _notify_play(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
- /* Kindly ignore this notification: it's received when seeking
- * in a stream */
-}
-
-static void _notify_pause(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
-
- MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- /* Change status to pause */
- mafw_gst_renderer_set_state(renderer, Paused);
-}
-
-static void _notify_seek(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
- mafw_gst_renderer_state_do_notify_seek(self, error);
-}
-
-static void _notify_buffer_status(MafwGstRendererState *self, gdouble percent,
- GError **error)
-{
- mafw_gst_renderer_state_do_notify_buffer_status (self, percent, error);
-}
-
-static void _notify_eos(MafwGstRendererState *self, GError **error)
-{
- MafwGstRenderer *renderer;
- MafwGstRendererMovementResult move_type;
- MafwGstRendererPlaybackMode mode;
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- /* Update playcount */
- if (renderer->update_playcount_id > 0) {
- g_source_remove(renderer->update_playcount_id);
- mafw_gst_renderer_update_stats(renderer);
- }
-
- /* Notice: playback has already stopped, so calling
- * mafw_gst_renderer_stop or mafw_gst_renderer_state_stop
- * here is an error.
- * To set the renderer state to Stopped use this instead:
- * mafw_gst_renderer_set_state(self->renderer, Stopped);
- */
-
- /* If we are not in playlist mode, switch to it,
- otherwise move to the next in the playlist */
- mode = mafw_gst_renderer_get_playback_mode(renderer);
- if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
- mafw_gst_renderer_worker_stop(self->renderer->worker);
- mafw_gst_renderer_set_state(self->renderer, Stopped);
- mafw_gst_renderer_set_playback_mode(
- renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
- mafw_gst_renderer_set_media_playlist(renderer);
-
- /* Do we have to resume playlist playback? */
- if (renderer->resume_playlist) {
- mafw_gst_renderer_state_play(self, error);
- }
- }
- else
- {
- gboolean is_stream = uri_is_stream(self->renderer->worker->media.location);
- if (is_stream
- && self->renderer->error_policy == MAFW_RENDERER_ERROR_POLICY_STOP
- && self->renderer->worker->media.length_nanos == -1
- && self->renderer->worker->media.seekable == SEEKABILITY_NO_SEEKABLE
- && self->renderer->worker->media.has_visual_content == FALSE)
- {
- /* Endless Radio stream. Stream has no length, it is not seekable or it is not video. */
- mafw_gst_renderer_worker_stop(self->renderer->worker);
- mafw_gst_renderer_set_state(self->renderer, Stopped);
- g_signal_emit_by_name(MAFW_EXTENSION(self->renderer), "error",
- MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_STREAM_DISCONNECTED,
- "EOS FOR ENDLESS STREAM");
- }
- else
- {
- /* Move to next in playlist */
- move_type =
- mafw_gst_renderer_move(renderer,
- MAFW_GST_RENDERER_MOVE_TYPE_NEXT,
- 0, error);
-
- switch (move_type)
- {
- case MAFW_GST_RENDERER_MOVE_RESULT_OK:
- mafw_gst_renderer_state_play(self, error);
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
- case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
- mafw_gst_renderer_worker_stop(self->renderer->worker);
- mafw_gst_renderer_set_state(self->renderer, Stopped);
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
- break;
- default:
- g_critical("Movement not controlled");
- }
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- Playlist editing signals
- ----------------------------------------------------------------------------*/
-
-static void _playlist_contents_changed(MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error)
-{
- MafwGstRendererPlaybackMode mode;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
-
- /* Play the new index only if we are not in standalone mode.
- Otherwise, when play_object finishes the new item will be
- played if that's been suggested with renderer->resume_playlist */
- mode = mafw_gst_renderer_get_playback_mode(self->renderer);
- if (clip_changed && mode == MAFW_GST_RENDERER_MODE_PLAYLIST) {
- mafw_gst_renderer_state_do_play(self, error);
- }
-}
-
-/*----------------------------------------------------------------------------
- Property methods
- ----------------------------------------------------------------------------*/
-
-GValue* _get_property_value(MafwGstRendererState *self, const gchar *name)
-{
- GValue *value = NULL;
-
- g_return_val_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self), value);
-
- if (!g_strcmp0(name, MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS)) {
- gboolean is_seekable =
- mafw_gst_renderer_worker_get_seekable(
- self->renderer->worker);
-
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_STRING);
- if (is_seekable) {
- g_value_set_string(value, "seek");
- } else {
- g_value_set_string(value, "");
- }
- }
-
- return value;
-}
-
-/*----------------------------------------------------------------------------
- Memory card event handlers
- ----------------------------------------------------------------------------*/
-
-static void _handle_pre_unmount(MafwGstRendererState *self,
- const gchar *mount_point)
-{
- gchar *mount_uri;
-
- /* If not playing anything, bail out */
- if (!self->renderer->media->uri) {
- return;
- }
-
- /* Check if mount point is URI or path, we need URI */
- if (!g_str_has_prefix(mount_point, "file://")) {
- mount_uri = g_filename_to_uri(mount_point, NULL, NULL);
- } else {
- mount_uri = g_strdup(mount_point);
- }
-
- /* Stop if playing from unmounted location */
- if (g_str_has_prefix(self->renderer->media->uri, mount_uri)) {
- mafw_gst_renderer_stop(MAFW_RENDERER(self->renderer),
- NULL,
- NULL);
- }
-
- g_free(mount_uri);
-}
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef MAFW_GST_RENDERER_STATE_PLAYING_H
-#define MAFW_GST_RENDERER_STATE_PLAYING_H
-
-
-#include "mafw-gst-renderer.h"
-#include "mafw-gst-renderer-state.h"
-
-G_BEGIN_DECLS
-
-/*----------------------------------------------------------------------------
- GObject type conversion macros
- ----------------------------------------------------------------------------*/
-
-#define MAFW_TYPE_GST_RENDERER_STATE_PLAYING \
- (mafw_gst_renderer_state_playing_get_type())
-#define MAFW_GST_RENDERER_STATE_PLAYING(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_GST_RENDERER_STATE_PLAYING, \
- MafwGstRendererStatePlaying))
-#define MAFW_IS_GST_RENDERER_STATE_PLAYING(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_GST_RENDERER_STATE_PLAYING))
-#define MAFW_GST_RENDERER_STATE_PLAYING_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_GST_RENDERER_STATE_PLAYING, \
- MafwGstRendererStatePlaying))
-#define MAFW_GST_RENDERER_STATE_PLAYING_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_GST_RENDERER_STATE_PLAYING, \
- MafwGstRendererStatePlayingClass))
-#define MAFW_IS_GST_RENDERER_STATE_PLAYING_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_GST_RENDERER_STATE_PLAYING))
-
-/*----------------------------------------------------------------------------
- Type definitions
- ----------------------------------------------------------------------------*/
-
-
-typedef struct _MafwGstRendererStatePlaying MafwGstRendererStatePlaying;
-typedef struct _MafwGstRendererStatePlayingClass MafwGstRendererStatePlayingClass;
-
-struct _MafwGstRendererStatePlayingClass {
- MafwGstRendererStateClass parent_class;
-};
-
-struct _MafwGstRendererStatePlaying {
- MafwGstRendererState parent;
-};
-
-GType mafw_gst_renderer_state_playing_get_type(void);
-
-GObject *mafw_gst_renderer_state_playing_new(MafwGstRenderer *renderer);
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <libmafw/mafw-errors.h>
-#include "mafw-gst-renderer-state-stopped.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-state-stopped"
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-static void _do_play(MafwGstRendererState *self, GError **error);
-static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
- GError **error);
-static void _do_stop(MafwGstRendererState *self, GError **error);
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-static void _do_next(MafwGstRendererState *self, GError **error);
-static void _do_previous(MafwGstRendererState *self, GError **error);
-static void _do_goto_index(MafwGstRendererState *self, guint index,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Notification metatada
- ----------------------------------------------------------------------------*/
-
-static void _notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Playlist editing signals
- ----------------------------------------------------------------------------*/
-
-static void _playlist_contents_changed(MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Property methods
- ----------------------------------------------------------------------------*/
-
-static GValue* _get_property_value(MafwGstRendererState *self,
- const gchar *name);
-
-/*----------------------------------------------------------------------------
- GObject initialization
- ----------------------------------------------------------------------------*/
-
-G_DEFINE_TYPE(MafwGstRendererStateStopped, mafw_gst_renderer_state_stopped,
- MAFW_TYPE_GST_RENDERER_STATE);
-
-static void mafw_gst_renderer_state_stopped_init(MafwGstRendererStateStopped *self)
-{
-}
-
-static void mafw_gst_renderer_state_stopped_class_init(
- MafwGstRendererStateStoppedClass *klass)
-{
- MafwGstRendererStateClass *state_klass;
-
- state_klass = MAFW_GST_RENDERER_STATE_CLASS(klass);
- g_return_if_fail(state_klass != NULL);
-
- state_klass->name = g_strdup("Stopped");
-
- /* Playback */
-
- state_klass->play = _do_play;
- state_klass->play_object = _do_play_object;
- state_klass->stop = _do_stop;
-
- /* Playlist */
-
- state_klass->next = _do_next;
- state_klass->previous = _do_previous;
- state_klass->goto_index = _do_goto_index;
-
- /* Metadata */
-
- state_klass->notify_metadata = _notify_metadata;
-
- /* Playlist editing signals */
-
- state_klass->playlist_contents_changed =
- _playlist_contents_changed;
-
- /* Property methods */
-
- state_klass->get_property_value = _get_property_value;
-}
-
-GObject *mafw_gst_renderer_state_stopped_new(MafwGstRenderer *renderer)
-{
- MafwGstRendererState *state;
-
- state = MAFW_GST_RENDERER_STATE(
- g_object_new(MAFW_TYPE_GST_RENDERER_STATE_STOPPED, NULL));
- state->renderer = renderer;
-
- return G_OBJECT(state);
-}
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-static void _do_play(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
- mafw_gst_renderer_state_do_play(self, error);
-}
-
-static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
- GError **error)
-{
- MafwGstRendererPlaybackMode cur_mode, prev_mode;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
-
- prev_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
- mafw_gst_renderer_state_do_play_object(self, object_id, error);
- cur_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
-
- /* If this happens it means that we interrupted playlist mode
- but we did so in Stopped state, so when play_object finishes
- we want to stay Stopped */
- if (cur_mode != prev_mode) {
- self->renderer->resume_playlist = FALSE;
- }
-}
-
-static void _do_stop(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
- /* We are already in Stopped state, so do nothing */
-}
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-static void _do_next(MafwGstRendererState *self, GError **error)
-{
- MafwGstRenderer *renderer = NULL;
- MafwGstRendererMovementResult value = MAFW_GST_RENDERER_MOVE_RESULT_OK;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- value = mafw_gst_renderer_move(renderer,
- MAFW_GST_RENDERER_MOVE_TYPE_NEXT,
- 0, error);
-
- switch (value) {
- case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
- case MAFW_GST_RENDERER_MOVE_RESULT_OK:
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
- g_set_error (error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_NO_MEDIA,
- "There is no playlist or media to play");
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
- mafw_playlist_iterator_reset(renderer->iterator, NULL);
- mafw_gst_renderer_set_media_playlist(renderer);
- break;
- default:
- g_critical("Movement not controlled");
- }
-}
-
-static void _do_previous(MafwGstRendererState *self, GError **error)
-{
- MafwGstRenderer *renderer = NULL;
- MafwGstRendererMovementResult value = MAFW_GST_RENDERER_MOVE_RESULT_OK;
-
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- value = mafw_gst_renderer_move(renderer,
- MAFW_GST_RENDERER_MOVE_TYPE_PREV,
- 0, error);
-
- switch (value) {
- case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
- case MAFW_GST_RENDERER_MOVE_RESULT_OK:
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_NO_MEDIA,
- "There is no playlist or media to play");
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
-
- mafw_playlist_iterator_move_to_last(renderer->iterator, NULL);
- mafw_gst_renderer_set_media_playlist(renderer);
- break;
- default:
- g_critical("Movement not controlled");
- }
-}
-
-static void _do_goto_index(MafwGstRendererState *self, guint index,
- GError **error)
-{
- MafwGstRenderer *renderer = NULL;
- MafwGstRendererMovementResult value = MAFW_GST_RENDERER_MOVE_RESULT_OK;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- value = mafw_gst_renderer_move(renderer,
- MAFW_GST_RENDERER_MOVE_TYPE_INDEX,
- index, error);
-
- switch (value) {
- case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
- case MAFW_GST_RENDERER_MOVE_RESULT_OK:
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_NO_MEDIA,
- "There is no playlist or media to play");
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_INDEX_OUT_OF_BOUNDS,
- "Index is out of bounds");
- break;
- default:
- g_critical("Movement not controlled");
- }
-}
-
-/*----------------------------------------------------------------------------
- Notification metatada
- ----------------------------------------------------------------------------*/
-
-static void _notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error)
-{
- g_debug("running _notify_metadata...");
- /* This happens because we issued a play() command, this moved us to
- Transitioning state, waiting for the URL of the objectid to play,
- but before we got the URL and moved to Playing state, a stop()
- command was issued. Now we got the results of the stopped play()
- command, so we just ignore the result and stay in Stopped state. */
-
-}
-
-/*----------------------------------------------------------------------------
- Playlist editing signals
- ----------------------------------------------------------------------------*/
-
-static void _playlist_contents_changed(MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
-
- /* Do nothing, we just stay in Stopped state in any case */
-}
-
-/*----------------------------------------------------------------------------
- Property methods
- ----------------------------------------------------------------------------*/
-
-GValue* _get_property_value(MafwGstRendererState *self, const gchar *name)
-{
- GValue *value = NULL;
-
- g_return_val_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self), value);
-
- if (!g_strcmp0(name, MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS)) {
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_STRING);
- g_value_set_string(value, "");
- }
-
- return value;
-}
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef MAFW_GST_RENDERER_STATE_STOPPED_H
-#define MAFW_GST_RENDERER_STATE_STOPPED_H
-
-
-#include "mafw-gst-renderer.h"
-#include "mafw-gst-renderer-state.h"
-
-G_BEGIN_DECLS
-
-/*----------------------------------------------------------------------------
- GObject type conversion macros
- ----------------------------------------------------------------------------*/
-
-#define MAFW_TYPE_GST_RENDERER_STATE_STOPPED \
- (mafw_gst_renderer_state_stopped_get_type())
-#define MAFW_GST_RENDERER_STATE_STOPPED(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_GST_RENDERER_STATE_STOPPED, \
- MafwGstRendererStateStopped))
-#define MAFW_IS_GST_RENDERER_STATE_STOPPED(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_GST_RENDERER_STATE_STOPPED))
-#define MAFW_GST_RENDERER_STATE_STOPPED_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_GST_RENDERER_STATE_STOPPED, \
- MafwGstRendererStateStopped))
-#define MAFW_GST_RENDERER_STATE_STOPPED_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_GST_RENDERER_STATE_STOPPED, \
- MafwGstRendererStateStoppedClass))
-#define MAFW_IS_GST_RENDERER_STATE_STOPPED_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_GST_RENDERER_STATE_STOPPED))
-
-/*----------------------------------------------------------------------------
- Type definitions
- ----------------------------------------------------------------------------*/
-
-
-typedef struct _MafwGstRendererStateStopped MafwGstRendererStateStopped;
-typedef struct _MafwGstRendererStateStoppedClass MafwGstRendererStateStoppedClass;
-
-struct _MafwGstRendererStateStoppedClass {
- MafwGstRendererStateClass parent_class;
-};
-
-struct _MafwGstRendererStateStopped {
- MafwGstRendererState parent;
-};
-
-GType mafw_gst_renderer_state_stopped_get_type(void);
-
-GObject *mafw_gst_renderer_state_stopped_new(MafwGstRenderer *renderer);
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <string.h>
-#include "mafw-gst-renderer-state-transitioning.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-state-transitioning"
-
-#define UPDATE_DELAY 10
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-static void _do_play(MafwGstRendererState *self, GError **error);
-static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
- GError **error);
-static void _do_pause(MafwGstRendererState *self, GError **error);
-static void _do_stop(MafwGstRendererState *self, GError **error);
-static void _do_resume(MafwGstRendererState *self, GError **error);
-static void _do_get_position(MafwGstRendererState *self, gint *seconds,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-static void _do_next(MafwGstRendererState *self, GError **error);
-static void _do_previous(MafwGstRendererState *self,GError **error);
-static void _do_goto_index(MafwGstRendererState *self, guint index,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Notification metatada
- ----------------------------------------------------------------------------*/
-
-static void _notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Notification worker
- ----------------------------------------------------------------------------*/
-
-static void _notify_play(MafwGstRendererState *self, GError **error);
-static void _notify_pause(MafwGstRendererState *self,GError **error);
-
-static void _notify_buffer_status(MafwGstRendererState *self,
- gdouble percent,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Playlist editing signals
- ----------------------------------------------------------------------------*/
-
-static void _playlist_contents_changed(MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Property methods
- ----------------------------------------------------------------------------*/
-
-static GValue* _get_property_value(MafwGstRendererState *self,
- const gchar *name);
-
-/*----------------------------------------------------------------------------
- GObject initialization
- ----------------------------------------------------------------------------*/
-
-G_DEFINE_TYPE(MafwGstRendererStateTransitioning,
- mafw_gst_renderer_state_transitioning,
- MAFW_TYPE_GST_RENDERER_STATE);
-
-static void mafw_gst_renderer_state_transitioning_init(
- MafwGstRendererStateTransitioning *self)
-{
-}
-
-static void mafw_gst_renderer_state_transitioning_class_init(
- MafwGstRendererStateTransitioningClass *klass)
-{
- MafwGstRendererStateClass *state_klass ;
-
- state_klass = MAFW_GST_RENDERER_STATE_CLASS(klass);
- g_return_if_fail(state_klass != NULL);
-
- state_klass->name = g_strdup("Transitioning");
-
- /* Playback */
-
- state_klass->play = _do_play;
- state_klass->play_object = _do_play_object;
- state_klass->stop = _do_stop;
- state_klass->pause = _do_pause;
- state_klass->resume = _do_resume;
- state_klass->get_position = _do_get_position;
-
- /* Playlist */
-
- state_klass->next = _do_next;
- state_klass->previous = _do_previous;
- state_klass->goto_index = _do_goto_index;
-
- /* Metadata */
-
- state_klass->notify_metadata = _notify_metadata;
-
- /* Notification worker */
-
- state_klass->notify_play = _notify_play;
- state_klass->notify_pause = _notify_pause;
- state_klass->notify_buffer_status = _notify_buffer_status;
-
- /* Playlist editing signals */
-
- state_klass->playlist_contents_changed =
- _playlist_contents_changed;
-
- /* Property methods */
-
- state_klass->get_property_value = _get_property_value;
-}
-
-GObject *mafw_gst_renderer_state_transitioning_new(MafwGstRenderer *renderer)
-{
- MafwGstRendererState *state;
-
- state = MAFW_GST_RENDERER_STATE(
- g_object_new(MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING, NULL));
- state->renderer = renderer;
-
- return G_OBJECT(state);
-}
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-static void _do_play(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
- mafw_gst_renderer_state_do_play(self, error);
-}
-
-static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
- GError **error)
-{
- MafwGstRendererPlaybackMode cur_mode, prev_mode;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
-
- prev_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
- mafw_gst_renderer_state_do_play_object(self, object_id, error);
- cur_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
-
- /* If this happens it means that we interrupted playlist playback
- so let's resume it when play_object is finished */
- if (cur_mode != prev_mode) {
- self->renderer->resume_playlist = TRUE;
- }
-}
-
-static void _do_stop(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
-
- /* Stop playback */
- mafw_gst_renderer_state_do_stop(self, error);
-}
-
-static void _do_pause(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
- g_debug("Got pause while transitioning");
- self->renderer->worker->stay_paused = TRUE;
-}
-
-static void _do_resume(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
- if (self->renderer->worker->stay_paused) {
- g_debug("Got resume while transitioning/paused");
- self->renderer->worker->stay_paused = FALSE;
- } else {
- g_set_error(error, MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_CANNOT_PLAY,
- "cannot resume in transitioning state without "
- "having paused before");
- }
-}
-
-static void _do_get_position(MafwGstRendererState *self, gint *seconds,
- GError **error)
-{
- *seconds = 0;
-}
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-static void _do_next(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
- mafw_gst_renderer_state_do_next(self, error);
-}
-
-static void _do_previous(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
- mafw_gst_renderer_state_do_prev(self, error);
-}
-
-static void _do_goto_index(MafwGstRendererState *self, guint index,
- GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
- mafw_gst_renderer_state_do_goto_index(self, index, error);
-}
-
-/*----------------------------------------------------------------------------
- Notification metatada
- ----------------------------------------------------------------------------*/
-
-static void _notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
-
- MafwGstRenderer *renderer;
- GValue *mval;
- gpointer value;
- gint nuris, i;
- gchar **uris;
- gchar *uri;
-
- g_debug("running _notify_metadata...");
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- /* If we have received metadata for the item that we are playing
- then play it */
- if (object_id && renderer->media->object_id &&
- !strcmp(object_id, renderer->media->object_id)) {
- /* Check how many uris provide the object_id */
- value = g_hash_table_lookup(metadata, MAFW_METADATA_KEY_URI);
- nuris = mafw_metadata_nvalues(value);
- if (nuris == 1) {
- mval = mafw_metadata_first(metadata,
- MAFW_METADATA_KEY_URI);
- g_assert(mval);
- g_free(renderer->media->uri);
- renderer->media->uri =
- g_strdup(g_value_get_string(mval));
- uri = renderer->media->uri;
- } else if (nuris > 1) {
- uris = g_new0(gchar *, nuris + 1);
- for (i = 0; i < nuris; i++) {
- mval = g_value_array_get_nth(value, i);
- uris[i] = (gchar *) g_value_get_string(mval);
- }
-
- /* Try the first URI, if that fails to play back another
- * one will be selected until we get a successful one or
- * all failed. On success, the selected URI will be
- * emitted as metadata */
- g_free(renderer->media->uri);
- renderer->media->uri = g_strdup(uris[0]);
- } else {
- g_assert_not_reached();
- }
-
- /* Set seekability property; currently, if several uris are
- * provided it uses the value of the first uri. If later another
- * uri is actually played, then this value should be changed. */
- mval = mafw_metadata_first(metadata,
- MAFW_METADATA_KEY_IS_SEEKABLE);
- if (mval != NULL) {
- renderer->media->seekability =
- g_value_get_boolean(mval) ?
- SEEKABILITY_SEEKABLE : SEEKABILITY_NO_SEEKABLE;
- g_debug("_notify_metadata: source seekability %d",
- renderer->media->seekability);
- } else {
- renderer->media->seekability = SEEKABILITY_UNKNOWN;
- g_debug("_notify_metadata: source seekability unknown");
- }
-
- /* Check for source duration to keep it updated if needed */
- mval = mafw_metadata_first(metadata,
- MAFW_METADATA_KEY_DURATION);
-
- if (mval != NULL) {
- renderer->media->duration = g_value_get_int(mval);
- g_debug("_notify_metadata: source duration %d",
- renderer->media->duration);
- } else {
- renderer->media->duration = -1;
- g_debug("_notify_metadata: source duration unknown");
- }
-
- /* Play the available uri(s) */
- if (nuris == 1) {
- mafw_gst_renderer_worker_play(renderer->worker, uri, NULL);
- } else {
- mafw_gst_renderer_worker_play_alternatives(
- renderer->worker, uris);
- g_free(uris);
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- Notification worker
- ----------------------------------------------------------------------------*/
-
-static void _notify_play(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
-
- MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- if (renderer->media->object_id)
- {
- renderer->update_playcount_id = g_timeout_add_seconds(
- UPDATE_DELAY,
- mafw_gst_renderer_update_stats,
- renderer);
- }
-
- mafw_gst_renderer_set_state(renderer, Playing);
-}
-
-static void _notify_pause(MafwGstRendererState *self, GError **error)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
-
- MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
- self->renderer->worker->stay_paused = FALSE;
- mafw_gst_renderer_set_state(renderer, Paused);
-}
-
-static void _notify_buffer_status(MafwGstRendererState *self, gdouble percent,
- GError **error)
-{
- mafw_gst_renderer_state_do_notify_buffer_status (self, percent, error);
-}
-
-/*----------------------------------------------------------------------------
- Playlist editing signals
- ----------------------------------------------------------------------------*/
-
-static void _playlist_contents_changed(MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error)
-{
- MafwGstRendererPlaybackMode mode;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
-
- /* Play the new index only if we are not in standalone mode.
- Otherwise, when play_object finishes the new item will be
- played if that's been suggested with renderer->resume_playlist */
- mode = mafw_gst_renderer_get_playback_mode(self->renderer);
- if (clip_changed && mode == MAFW_GST_RENDERER_MODE_PLAYLIST) {
- mafw_gst_renderer_state_do_play(self, error);
- }
-}
-
-/*----------------------------------------------------------------------------
- Property methods
- ----------------------------------------------------------------------------*/
-
-GValue* _get_property_value(MafwGstRendererState *self, const gchar *name)
-{
- GValue *value = NULL;
-
- g_return_val_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self),
- value);
-
- if (!g_strcmp0(name, MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS)) {
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_STRING);
- g_value_set_string(value, "");
- }
-
- return value;
-}
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef MAFW_GST_RENDERER_STATE_TRANSITIONING_H
-#define MAFW_GST_RENDERER_STATE_TRANSITIONING_H
-
-
-#include "mafw-gst-renderer.h"
-#include "mafw-gst-renderer-state.h"
-#include "mafw-gst-renderer-utils.h"
-
-G_BEGIN_DECLS
-
-/*----------------------------------------------------------------------------
- GObject type conversion macros
- ----------------------------------------------------------------------------*/
-
-#define MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING \
- (mafw_gst_renderer_state_transitioning_get_type())
-#define MAFW_GST_RENDERER_STATE_(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), \
- MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING, \
- MafwGstRendererStateTransitioning))
-#define MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
- MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING))
-#define MAFW_GST_RENDERER_STATE_TRANSITIONING_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), \
- MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING, \
- MafwGstRendererStateTransitioning))
-#define MAFW_GST_RENDERER_STATE_TRANSITIONING_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), \
- MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING, \
- MafwGstRendererStateTransitioningClass))
-#define MAFW_IS_GST_RENDERER_STATE_TRANSITIONING_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), \
- MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING))
-
-/*----------------------------------------------------------------------------
- Type definitions
- ----------------------------------------------------------------------------*/
-
-
-typedef struct _MafwGstRendererStateTransitioning MafwGstRendererStateTransitioning;
-typedef struct _MafwGstRendererStateTransitioningClass MafwGstRendererStateTransitioningClass;
-
-struct _MafwGstRendererStateTransitioningClass {
- MafwGstRendererStateClass parent_class;
-};
-
-struct _MafwGstRendererStateTransitioning {
- MafwGstRendererState parent;
-};
-
-GType mafw_gst_renderer_state_transitioning_get_type(void);
-
-GObject *mafw_gst_renderer_state_transitioning_new(MafwGstRenderer *renderer);
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <libmafw/mafw-renderer.h>
-#include <libmafw/mafw-errors.h>
-
-#include "mafw-gst-renderer.h"
-#include "mafw-gst-renderer-state.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-state"
-
-/*----------------------------------------------------------------------------
- Default playback implementations
- ----------------------------------------------------------------------------*/
-
-static void _default_play(MafwGstRendererState *self, GError **error)
-{
- g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
- "Play: operation not allowed in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-
-static void _default_play_object(MafwGstRendererState *self,
- const gchar *objectid,
- GError **error)
-{
- g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
- "Play object: operation not allowed in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-static void _default_stop(MafwGstRendererState *self, GError **error)
-{
- g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_STOP,
- "Stop: operation not allowed in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-static void _default_pause(MafwGstRendererState *self, GError **error)
-{
- g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PAUSE,
- "Pause: operation not allowed in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-static void _default_resume(MafwGstRendererState *self, GError **error)
-{
- g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
- "Resume: operation not allowed in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-static void _default_set_position (MafwGstRendererState *self,
- MafwRendererSeekMode mode, gint seconds,
- GError **error)
-{
- g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
- "Set position: operation not allowed in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-static void _default_get_position (MafwGstRendererState *self,
- gint *seconds,
- GError **error)
-{
- g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_GET_POSITION,
- "Get position: operation not allowed in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-/*----------------------------------------------------------------------------
- Default playlist implementations
- ----------------------------------------------------------------------------*/
-
-static void _default_next(MafwGstRendererState *self, GError **error)
-{
- g_set_error(error, MAFW_EXTENSION_ERROR, MAFW_EXTENSION_ERROR_FAILED,
- "Next: operation not allowed in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-static void _default_previous(MafwGstRendererState *self, GError **error)
-{
- g_set_error(error, MAFW_EXTENSION_ERROR, MAFW_EXTENSION_ERROR_FAILED,
- "Previous: Operation not allowed in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-static void _default_goto_index(MafwGstRendererState *self, guint index,
- GError **error)
-{
- g_set_error(error, MAFW_EXTENSION_ERROR, MAFW_EXTENSION_ERROR_FAILED,
- "Goto index: operation not allowed in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-/*----------------------------------------------------------------------------
- Default notify metadata implementation
- ----------------------------------------------------------------------------*/
-
-static void _default_notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error)
-{
-
- g_critical("Notify metadata: got unexpected metadata in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-/*----------------------------------------------------------------------------
- Default notify worker implementations
- ----------------------------------------------------------------------------*/
-
-static void _default_notify_play(MafwGstRendererState *self, GError **error)
-{
- g_critical("Notify play: unexpected Play notification received in %s "
- "state", MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-static void _default_notify_pause(MafwGstRendererState *self, GError **error)
-{
-
- g_critical("Notify pause: unexpected Pause notification received %s "
- "state", MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-static void _default_notify_seek(MafwGstRendererState *self, GError **error)
-{
- g_critical("Notify seek: incorrect operation in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-static void _default_notify_buffer_status(MafwGstRendererState *self,
- gdouble percent,
- GError **error)
-{
- g_critical("Notify buffer status: incorrect operation in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-
-static void _default_notify_eos(MafwGstRendererState *self, GError **error)
-{
- g_critical("Notify eos: incorrect operation in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-/*----------------------------------------------------------------------------
- Default playlist editing signal handlers implementation
- ----------------------------------------------------------------------------*/
-
-static void _default_playlist_contents_changed(MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error)
-{
- g_warning("playlist::contents-changed not implemented in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-/*----------------------------------------------------------------------------
- Default property methods implementation
- ----------------------------------------------------------------------------*/
-
-static GValue* _default_get_property_value(MafwGstRendererState *self,
- const gchar *name)
-{
- g_warning("get_property_value function not implemented in %s state",
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
- return NULL;
-}
-
-/*----------------------------------------------------------------------------
- Default memory card event handlers implementation
- ----------------------------------------------------------------------------*/
-
-static void _default_handle_pre_unmount(MafwGstRendererState *self,
- const gchar *mount_point)
-{
- g_debug("pre-unmount signal received: %s in state %s", mount_point,
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
-}
-
-/*----------------------------------------------------------------------------
- GObject initialization
- ----------------------------------------------------------------------------*/
-
-G_DEFINE_ABSTRACT_TYPE(MafwGstRendererState, mafw_gst_renderer_state,
- G_TYPE_OBJECT);
-
-static void mafw_gst_renderer_state_init(MafwGstRendererState *self)
-{
-}
-
-static void mafw_gst_renderer_state_class_init(MafwGstRendererStateClass *klass)
-{
- /* Playback */
-
- klass->play = _default_play;
- klass->play_object = _default_play_object;
- klass->stop = _default_stop;
- klass->pause = _default_pause;
- klass->resume = _default_resume;
- klass->set_position = _default_set_position;
- klass->get_position = _default_get_position;
-
- /* Playlist */
-
- klass->next = _default_next;
- klass->previous = _default_previous;
- klass->goto_index = _default_goto_index;
-
- /* Notification metadata */
-
- klass->notify_metadata = _default_notify_metadata;
-
- /* Notification worker */
-
- klass->notify_play = _default_notify_play;
- klass->notify_pause = _default_notify_pause;
- klass->notify_seek = _default_notify_seek;
- klass->notify_buffer_status = _default_notify_buffer_status;
- klass->notify_eos = _default_notify_eos;
-
- klass->notify_eos = _default_notify_eos;
-
- /* Playlist editing signals */
-
- klass->playlist_contents_changed =
- _default_playlist_contents_changed;
-
- /* Property methods */
-
- klass->get_property_value = _default_get_property_value;
-
- /* Memory card event handlers */
-
- klass->handle_pre_unmount = _default_handle_pre_unmount;
-}
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_play(MafwGstRendererState *self, GError **error)
-
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->play(self, error);
-}
-
-void mafw_gst_renderer_state_play_object(MafwGstRendererState *self,
- const gchar *object_id,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->play_object(self, object_id,
- error);
-}
-
-void mafw_gst_renderer_state_stop(MafwGstRendererState *self, GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->stop(self, error);
-}
-
-void mafw_gst_renderer_state_pause(MafwGstRendererState *self, GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->pause(self, error);
-}
-
-void mafw_gst_renderer_state_resume(MafwGstRendererState *self, GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->resume(self, error);
-}
-
-void mafw_gst_renderer_state_set_position(MafwGstRendererState *self,
- MafwRendererSeekMode mode, gint seconds,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->set_position(self, mode, seconds,
- error);
-}
-
-void mafw_gst_renderer_state_get_position(MafwGstRendererState *self,
- gint *seconds,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->get_position(self, seconds,
- error);
-}
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_next(MafwGstRendererState *self, GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->next(self, error);
-}
-
-void mafw_gst_renderer_state_previous(MafwGstRendererState *self, GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->previous(self, error);
-}
-
-void mafw_gst_renderer_state_goto_index(MafwGstRendererState *self, guint index,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->goto_index(self, index, error);
-
-}
-
-/*----------------------------------------------------------------------------
- Notification metatada
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_metadata(self, object_id,
- metadata,
- error);
-}
-
-/*----------------------------------------------------------------------------
- Notification worker
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_notify_play(MafwGstRendererState *self,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_play(self, error);
-}
-
-void mafw_gst_renderer_state_notify_pause(MafwGstRendererState *self,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_pause(self, error);
-}
-
-void mafw_gst_renderer_state_notify_seek(MafwGstRendererState *self,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_seek(self, error);
-}
-
-void mafw_gst_renderer_state_notify_buffer_status(MafwGstRendererState *self,
- gdouble percent,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_buffer_status(self,
- percent,
- error);
-}
-
-void mafw_gst_renderer_state_notify_eos(MafwGstRendererState *self,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_eos(self, error);
-}
-
-/*----------------------------------------------------------------------------
- Playlist editing handlers
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_playlist_contents_changed_handler(
- MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->playlist_contents_changed(
- self,
- clip_changed,
- error);
-}
-
-/*----------------------------------------------------------------------------
- Property methods
- ----------------------------------------------------------------------------*/
-
-GValue* mafw_gst_renderer_state_get_property_value(MafwGstRendererState *self,
- const gchar *name)
-{
- return MAFW_GST_RENDERER_STATE_GET_CLASS(self)->get_property_value(
- self,
- name);
-}
-
-/*----------------------------------------------------------------------------
- Memory card event handlers
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_handle_pre_unmount(MafwGstRendererState *self,
- const gchar *mount_point)
-{
- MAFW_GST_RENDERER_STATE_GET_CLASS(self)->
- handle_pre_unmount(self, mount_point);
-}
-
-/*----------------------------------------------------------------------------
- Helpers
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_do_play(MafwGstRendererState *self, GError **error)
-{
- MafwGstRenderer *renderer;
- GError *gm_error = NULL;
- MafwGstRendererPlaybackMode mode;
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- /* Stop any on going playback */
- mafw_gst_renderer_worker_stop(renderer->worker);
-
- /* Play command only affects playlists, so switch to playlist
- mode first if necessary */
- mode = mafw_gst_renderer_get_playback_mode(renderer);
- if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
- mafw_gst_renderer_set_playback_mode(
- renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
- mafw_gst_renderer_set_media_playlist(renderer);
- }
-
- /* Do we have any objectid to play? Otherwise we cannot do it */
- if (renderer->media->object_id) {
- /* If so, resolve URI for this objectid */
- mafw_gst_renderer_get_metadata(renderer,
- renderer->media->object_id,
- &gm_error);
- if (gm_error) {
- MafwGstRendererErrorClosure *error_closure;
- if (error) {
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_NO_MEDIA,
- "Unable to find media");
- }
-
- /* This is a playback error: execute error policy */
- error_closure = g_new0(MafwGstRendererErrorClosure, 1);
- error_closure->renderer = renderer;
- error_closure->error = g_error_copy(gm_error);
- g_idle_add(mafw_gst_renderer_manage_error_idle,
- error_closure);
-
- g_error_free(gm_error);
- } else {
- mafw_gst_renderer_set_state(renderer, Transitioning);
- }
- } else if (error) {
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_NO_MEDIA,
- "There is no media to play");
- mafw_gst_renderer_set_state(renderer, Stopped);
- }
-}
-
-void mafw_gst_renderer_state_do_play_object(MafwGstRendererState *self,
- const gchar *object_id,
- GError **error)
-{
- MafwGstRenderer *renderer;
- GError *gm_error = NULL;
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- /* Stop any ongoing playback */
- mafw_gst_renderer_worker_stop(renderer->worker);
-
- if (object_id) {
- /* Switch to standalone mode */
- mafw_gst_renderer_set_playback_mode(
- renderer, MAFW_GST_RENDERER_MODE_STANDALONE);
-
- mafw_gst_renderer_set_object(renderer, object_id);
- mafw_gst_renderer_get_metadata(renderer,
- renderer->media->object_id,
- &gm_error);
- if (gm_error) {
- MafwGstRendererErrorClosure *error_closure;
- if (error) {
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_NO_MEDIA,
- "Unable to find media");
- }
-
- /* This is a playback error: execute error policy */
- error_closure = g_new0(MafwGstRendererErrorClosure, 1);
- error_closure->renderer = renderer;
- error_closure->error = g_error_copy(gm_error);
- g_idle_add(mafw_gst_renderer_manage_error_idle,
- error_closure);
- g_error_free(gm_error);
- } else {
- /* Play object has been successful */
- mafw_gst_renderer_set_state(renderer, Transitioning);
- }
- } else if (error) {
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_NO_MEDIA,
- "There is no media to play");
- mafw_gst_renderer_set_state(renderer, Stopped);
- }
-}
-
-void mafw_gst_renderer_state_do_stop(MafwGstRendererState *self, GError **error)
-{
- MafwGstRenderer *renderer;
- MafwGstRendererPlaybackMode mode;
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- /* Stop any ongoing playback */
- mafw_gst_renderer_worker_stop(renderer->worker);
-
- /* Cancel update */
- if (renderer->update_playcount_id > 0) {
- g_source_remove(renderer->update_playcount_id);
- renderer->update_playcount_id = 0;
- }
-
- /* Set new state */
- mafw_gst_renderer_set_state(renderer, Stopped);
-
- /* If we were playing a standalone object, then go back
- to playlist mode and stay stopped */
- mode = mafw_gst_renderer_get_playback_mode(renderer);
- if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
- mafw_gst_renderer_set_playback_mode(
- renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
- mafw_gst_renderer_set_media_playlist(renderer);
- }
-}
-
-void mafw_gst_renderer_state_do_next (MafwGstRendererState *self, GError **error)
-{
- MafwGstRenderer *renderer;
- MafwGstRendererMovementResult move_type;
- MafwGstRendererPlaybackMode mode;
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- /* If we are in standalone mode, we switch back to playlist
- * mode. Then we resume playback only if renderer->resume_playlist
- * was set.
- * If we are in playlist mode we just move to the next and
- * play.
- */
- mode = mafw_gst_renderer_get_playback_mode(renderer);
- if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
- mafw_gst_renderer_set_playback_mode(
- renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
- mafw_gst_renderer_set_media_playlist(renderer);
- }
-
- move_type = mafw_gst_renderer_move(renderer,
- MAFW_GST_RENDERER_MOVE_TYPE_NEXT,
- 0, error);
- switch (move_type) {
- case MAFW_GST_RENDERER_MOVE_RESULT_OK:
- if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST ||
- renderer->resume_playlist) {
- /* We issued the comand in playlist mode, or
- in standalone mode but with resume_playlist
- set, so let's play the new item */
- mafw_gst_renderer_state_play(self, error);
-
- } else {
- /* We issued the command in standalone mode and we
- do not want to resume playlist, so let's
- move to Stopped */
- mafw_gst_renderer_state_stop(self, NULL);
- }
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_NO_MEDIA,
- "There is no playlist or media to play");
- mafw_gst_renderer_state_stop(self, NULL);
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
- /* Normal mode */
- mafw_playlist_iterator_reset(renderer->iterator, NULL);
- mafw_gst_renderer_set_media_playlist(renderer);
- mafw_gst_renderer_state_play(self, error);
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
- break;
- default:
- g_critical("Movement not controlled");
- }
-}
-
-void mafw_gst_renderer_state_do_prev(MafwGstRendererState *self, GError **error)
-{
- MafwGstRenderer *renderer;
- MafwGstRendererMovementResult move_type;
- MafwGstRendererPlaybackMode mode;
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- mode = mafw_gst_renderer_get_playback_mode(renderer);
- if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
- mafw_gst_renderer_set_playback_mode(
- renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
- mafw_gst_renderer_set_media_playlist(renderer);
- }
-
- move_type = mafw_gst_renderer_move(renderer,
- MAFW_GST_RENDERER_MOVE_TYPE_PREV,
- 0, error);
- switch (move_type) {
- case MAFW_GST_RENDERER_MOVE_RESULT_OK:
- if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST ||
- renderer->resume_playlist) {
- /* We issued the comand in playlist mode, or
- in standalone mode but with resume_playlist
- set, so let's play the new item */
- mafw_gst_renderer_state_play(self, error);
-
- } else {
- /* We issued the command in standalone mode and we
- do not want to resume playlist, so let's
- move to Stopped */
- mafw_gst_renderer_state_stop(self, NULL);
- }
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_NO_MEDIA,
- "There is no playlist or media to play");
- mafw_gst_renderer_state_stop(self, NULL);
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
- /* Normal mode */
- mafw_playlist_iterator_move_to_last(renderer->iterator, NULL);
- mafw_gst_renderer_set_media_playlist(renderer);
- mafw_gst_renderer_state_play(self, error);
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
- break;
- default:
- g_critical("Movement not controlled");
- }
-}
-
-
-void mafw_gst_renderer_state_do_goto_index(MafwGstRendererState *self,
- guint index,
- GError **error)
-{
- MafwGstRenderer *renderer;
- MafwGstRendererMovementResult move_type;
- MafwGstRendererPlaybackMode mode;
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- /* If we are in standalone mode, we switch back to playlist
- * mode. Then we resume playback only if renderer->resume_playlist
- * was set.
- * If we are in playlist mode we just move to the next and
- * play.
- */
- mode = mafw_gst_renderer_get_playback_mode(renderer);
- if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
- mafw_gst_renderer_set_playback_mode(
- renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
- mafw_gst_renderer_set_media_playlist(renderer);
- }
-
- move_type = mafw_gst_renderer_move(renderer, MAFW_GST_RENDERER_MOVE_TYPE_INDEX, index, error);
-
- switch (move_type) {
- case MAFW_GST_RENDERER_MOVE_RESULT_OK:
- if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST ||
- renderer->resume_playlist) {
- /* We issued the comand in playlist mode, or
- in standalone mode but with resume_playlist
- set, so let's play the new item */
- mafw_gst_renderer_state_play(self, error);
-
- } else {
- /* We issued the command in standalone mode and we
- do not want to resume playlist, so let's
- move to Stopped */
- mafw_gst_renderer_state_stop(self, NULL);
- }
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_NO_MEDIA,
- "There is no playlist or media to play");
- mafw_gst_renderer_state_stop(self, NULL);
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
- g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_INDEX_OUT_OF_BOUNDS,
- "Index is out of bounds");
- mafw_gst_renderer_state_stop(self, NULL);
- break;
- case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
- break;
- default:
- g_critical("Movement not controlled");
- }
-}
-
-void mafw_gst_renderer_state_do_get_position(MafwGstRendererState *self,
- gint *seconds,
- GError **error)
-{
- *seconds = mafw_gst_renderer_worker_get_position(self->renderer->worker);
- if (*seconds < 0) {
- *seconds = 0;
- g_set_error(error, MAFW_EXTENSION_ERROR,
- MAFW_RENDERER_ERROR_CANNOT_GET_POSITION,
- "Position query failed");
- }
-}
-
-void mafw_gst_renderer_state_do_set_position(MafwGstRendererState *self,
- MafwRendererSeekMode mode,
- gint seconds,
- GError **error)
-{
- MafwGstRenderer *renderer;
- GstSeekType seektype;
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- /* TODO Gst stuff should be moved to worker, not handled here... */
- if (mode == SeekAbsolute) {
- if (seconds < 0) {
- seektype = GST_SEEK_TYPE_END;
- seconds *= -1;
- } else {
- seektype = GST_SEEK_TYPE_SET;
- }
- } else if (mode == SeekRelative) {
- seektype = GST_SEEK_TYPE_CUR;
- } else {
- g_critical("Unknown seek mode: %d", mode);
- g_set_error(error, MAFW_EXTENSION_ERROR,
- MAFW_EXTENSION_ERROR_INVALID_PARAMS,
- "Unknown seek mode: %d", mode);
- return;
- }
- if (renderer->seek_pending) {
- g_debug("seek pending, storing position %d", seconds);
- renderer->seek_type_pending = seektype;
- renderer->seeking_to = seconds;
- } else {
- renderer->seek_pending = TRUE;
- mafw_gst_renderer_worker_set_position(renderer->worker,
- seektype,
- seconds,
- error);
- }
-}
-
-void mafw_gst_renderer_state_do_notify_seek(MafwGstRendererState *self,
- GError **error)
-{
- MafwGstRenderer *renderer;
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- if (renderer->seeking_to != -1) {
- renderer->seek_pending = TRUE;
- mafw_gst_renderer_worker_set_position(renderer->worker,
- renderer->seek_type_pending,
- renderer->seeking_to,
- NULL);
- } else {
- renderer->seek_pending = FALSE;
- }
- renderer->seeking_to = -1;
-}
-
-void mafw_gst_renderer_state_do_notify_buffer_status(MafwGstRendererState *self,
- gdouble percent,
- GError **error)
-{
- MafwGstRenderer *renderer = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER_STATE(self));
-
- renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
-
- mafw_renderer_emit_buffering_info(MAFW_RENDERER(renderer), percent / 100.0);
-}
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef MAFW_GST_RENDERER_STATE_H
-#define MAFW_GST_RENDERER_STATE_H
-
-
-#include <glib-object.h>
-#include "mafw-gst-renderer-worker.h"
-
-/* Solving the cyclic dependencies */
-typedef struct _MafwGstRendererState MafwGstRendererState;
-typedef struct _MafwGstRendererStateClass MafwGstRendererStateClass;
-#include "mafw-gst-renderer.h"
-
-G_BEGIN_DECLS
-
-/*----------------------------------------------------------------------------
- GObject type conversion macros
- ----------------------------------------------------------------------------*/
-
-#define MAFW_TYPE_GST_RENDERER_STATE \
- (mafw_gst_renderer_state_get_type())
-#define MAFW_GST_RENDERER_STATE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_GST_RENDERER_STATE, \
- MafwGstRendererState))
-#define MAFW_IS_GST_RENDERER_STATE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_GST_RENDERER_STATE))
-#define MAFW_GST_RENDERER_STATE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_GST_RENDERER_STATE, \
- MafwGstRendererStateClass))
-#define MAFW_GST_RENDERER_STATE_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_GST_RENDERER_STATE, \
- MafwGstRendererStateClass))
-#define MAFW_IS_GST_RENDERER_STATE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_GST_RENDERER_STATE))
-
-/*----------------------------------------------------------------------------
- Type definitions
- ----------------------------------------------------------------------------*/
-
-
-struct _MafwGstRendererStateClass {
- GObjectClass parent_class;
- const gchar* name;
-
- /* Playback */
-
- void (*play)(MafwGstRendererState *self, GError **error);
- void (*play_object)(MafwGstRendererState *self, const gchar *object_id,
- GError **error);
- void (*stop)(MafwGstRendererState *self, GError **error);
- void (*pause)(MafwGstRendererState *self, GError **error);
- void (*resume)(MafwGstRendererState *self, GError **error);
- void (*set_position) (MafwGstRendererState *self,
- MafwRendererSeekMode mode, gint seconds,
- GError **error);
- void (*get_position) (MafwGstRendererState *self,
- gint *seconds,
- GError **error);
-
- /* Playlist */
-
- void (*next)(MafwGstRendererState *self, GError **error);
- void (*previous)(MafwGstRendererState *self, GError **error);
- void (*goto_index)(MafwGstRendererState *self, guint index,
- GError **error);
-
- /* Notification metadata */
-
- void (*notify_metadata)(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error);
-
-
- /* Notifications */
-
- void (*notify_play)(MafwGstRendererState *self, GError **error);
- void (*notify_pause)(MafwGstRendererState *self, GError **error);
- void (*notify_seek)(MafwGstRendererState *self, GError **error);
- void (*notify_buffer_status)(MafwGstRendererState *self, gdouble percent,
- GError **error);
- void (*notify_eos) (MafwGstRendererState *self, GError **error);
-
- /* Playlist editing signals */
-
- void (*playlist_contents_changed)(MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error);
- /* Property methods */
-
- GValue* (*get_property_value)(MafwGstRendererState *self,
- const gchar *name);
-
- /* Memory card event handlers */
-
- void (*handle_pre_unmount)(MafwGstRendererState *self,
- const gchar *mount_point);
-};
-
-struct _MafwGstRendererState {
- GObject parent;
-
- MafwGstRenderer *renderer;
-};
-
-GType mafw_gst_renderer_state_get_type(void);
-
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_play(MafwGstRendererState *self, GError **error);
-void mafw_gst_renderer_state_play_object(MafwGstRendererState *self,
- const gchar *object_id,
- GError **error);
-void mafw_gst_renderer_state_stop(MafwGstRendererState *self, GError **error);
-void mafw_gst_renderer_state_pause(MafwGstRendererState *self, GError **error);
-void mafw_gst_renderer_state_resume(MafwGstRendererState *self, GError **error);
-void mafw_gst_renderer_state_set_position(MafwGstRendererState *self,
- MafwRendererSeekMode mode, gint seconds,
- GError **error);
-void mafw_gst_renderer_state_get_position(MafwGstRendererState *self,
- gint *seconds,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_next(MafwGstRendererState *self, GError **error);
-void mafw_gst_renderer_state_previous(MafwGstRendererState *self, GError **error);
-void mafw_gst_renderer_state_goto_index(MafwGstRendererState *self, guint index,
- GError **error);
-
-
-/*----------------------------------------------------------------------------
- Notification metatada
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_notify_metadata(MafwGstRendererState *self,
- const gchar *object_id,
- GHashTable *metadata,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Notification worker
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_notify_play(MafwGstRendererState *self,
- GError **error);
-void mafw_gst_renderer_state_notify_pause(MafwGstRendererState *self,
- GError **error);
-void mafw_gst_renderer_state_notify_seek(MafwGstRendererState *self,
- GError **error);
-void mafw_gst_renderer_state_notify_buffer_status(MafwGstRendererState *self,
- gdouble percent,
- GError **error);
-void mafw_gst_renderer_state_notify_eos(MafwGstRendererState *self,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Playlist editing handlers
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_playlist_contents_changed_handler(
- MafwGstRendererState *self,
- gboolean clip_changed,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Property methods
- ----------------------------------------------------------------------------*/
-
-GValue* mafw_gst_renderer_state_get_property_value(MafwGstRendererState *self,
- const gchar *name);
-
-/*----------------------------------------------------------------------------
- Memory card event handlers
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_handle_pre_unmount(MafwGstRendererState *self,
- const gchar *mount_point);
-
-/*----------------------------------------------------------------------------
- Helpers
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_state_do_play(MafwGstRendererState *self, GError **error);
-void mafw_gst_renderer_state_do_play_object(MafwGstRendererState *self,
- const gchar *object_id,
- GError **error);
-void mafw_gst_renderer_state_do_stop(MafwGstRendererState *self,
- GError **error);
-void mafw_gst_renderer_state_do_next(MafwGstRendererState *self,
- GError **error);
-void mafw_gst_renderer_state_do_prev(MafwGstRendererState *self,
- GError **error);
-void mafw_gst_renderer_state_do_goto_index(MafwGstRendererState *self,
- guint index,
- GError **error);
-void mafw_gst_renderer_state_do_set_position(MafwGstRendererState *self,
- MafwRendererSeekMode mode, gint seconds,
- GError **error);
-void mafw_gst_renderer_state_do_get_position(MafwGstRendererState *self,
- gint *seconds,
- GError **error);
-void mafw_gst_renderer_state_do_notify_seek(MafwGstRendererState *self,
- GError **error);
-void mafw_gst_renderer_state_do_notify_buffer_status(MafwGstRendererState *self,
- gdouble percent,
- GError **error);
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <glib.h>
-
-#include <string.h>
-#include <gio/gio.h>
-
-#include "mafw-gst-renderer-utils.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-utils"
-
-/**
- * convert_utf8:
- * @src: string.
- * @dst: location for utf8 version of @src.
- *
- * Tries to convert @src into UTF-8, placing it into @dst.
- *
- * Returns: TRUE on success.
- */
-gboolean convert_utf8(const gchar *src, gchar **dst)
-{
- GError *error;
-
- if (!src)
- return FALSE;
- if (g_utf8_validate(src, -1, NULL)) {
- *dst = g_strdup(src);
- return TRUE;
- }
- error = NULL;
- *dst = g_locale_to_utf8(src, -1, NULL, NULL, &error);
- if (error) {
- g_warning("utf8 conversion failed '%s' (%d: %s)",
- src, error->code, error->message);
- g_error_free(error);
- return FALSE;
- }
- return TRUE;
-}
-
-gboolean uri_is_playlist(const gchar *uri) {
- /* TODO: Return if the uri is a playlist or not, using the mime type
- instead of the file extension. */
- if ((g_str_has_suffix(uri, ".pls")) ||
- (g_str_has_suffix(uri, ".m3u")) ||
- (g_str_has_suffix(uri, ".smil")) ||
- (g_str_has_suffix(uri, ".smi")) ||
- (g_str_has_suffix(uri, ".wpl")) ||
- (g_str_has_suffix(uri, ".wax")) ||
- (g_str_has_suffix(uri, ".uni")) ||
- (g_str_has_suffix(uri, ".ram")) ||
-/* (g_str_has_suffix(uri, ".ra")) || */
- (g_str_has_suffix(uri, ".asx")) ||
- (g_str_has_suffix(uri, ".rpm")))
- {
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * uri_is_stream:
- * @uri: the URI to be checked.
- *
- * Check if given URI is a stream (not a local resource). To not depend on
- * gnomevfs for this, we assume everything that doesn't start with "file://" is
- * a stream.
- *
- * Returns: TRUE if the URI is not local.
- */
-gboolean uri_is_stream(const gchar *uri)
-{
- if (uri == NULL) {
- return FALSE;
- } else {
- return !g_str_has_prefix(uri, "file://");
- }
-}
-
-/*
- * Imported from totem-uri.c
- * Copyright (C) 2004 Bastien Nocera
- */
-
-/* List from xine-lib's demux_sputext.c */
-static const char subtitle_ext[][4] = {
- "sub",
- "srt",
- "smi",
- "ssa",
- "ass",
- "asc"
-};
-
-static inline gboolean
-uri_exists (const char *uri)
-{
- GFile *file = g_file_new_for_uri (uri);
- if (file != NULL) {
- if (g_file_query_exists (file, NULL)) {
- g_object_unref (file);
- return TRUE;
- }
- g_object_unref (file);
- }
- return FALSE;
-}
-
-static char *
-uri_get_subtitle_for_uri (const char *uri)
-{
- char *subtitle;
- guint len, i;
- gint suffix;
-
- /* Find the filename suffix delimiter */
- len = strlen (uri);
- for (suffix = len - 1; suffix > 0; suffix--) {
- if (uri[suffix] == G_DIR_SEPARATOR ||
- (uri[suffix] == '/')) {
- /* This filename has no extension; we'll need to
- * add one */
- suffix = len;
- break;
- }
- if (uri[suffix] == '.') {
- /* Found our extension marker */
- break;
- }
- }
- if (suffix < 0)
- return NULL;
-
- /* Generate a subtitle string with room at the end to store the
- * 3 character extensions for which we want to search */
- subtitle = g_malloc0 (suffix + 4 + 1);
- g_return_val_if_fail (subtitle != NULL, NULL);
- g_strlcpy (subtitle, uri, suffix + 4 + 1);
- g_strlcpy (subtitle + suffix, ".???", 5);
-
- /* Search for any files with one of our known subtitle extensions */
- for (i = 0; i < G_N_ELEMENTS (subtitle_ext) ; i++) {
- char *subtitle_ext_upper;
- memcpy (subtitle + suffix + 1, subtitle_ext[i], 3);
-
- if (uri_exists (subtitle))
- return subtitle;
-
- /* Check with upper-cased extension */
- subtitle_ext_upper = g_ascii_strup (subtitle_ext[i], -1);
- memcpy (subtitle + suffix + 1, subtitle_ext_upper, 3);
- g_free (subtitle_ext_upper);
-
- if (uri_exists (subtitle))
- return subtitle;
- }
- g_free (subtitle);
- return NULL;
-}
-
-static char *
-uri_get_subtitle_in_subdir (GFile *file, const char *subdir)
-{
- char *filename, *subtitle, *full_path_str;
- GFile *parent, *full_path, *directory;
-
- /* Get the sibling directory @subdir of the file @file */
- parent = g_file_get_parent (file);
- directory = g_file_get_child (parent, subdir);
- g_object_unref (parent);
-
- /* Get the file of the same name as @file in the @subdir directory */
- filename = g_file_get_basename (file);
- full_path = g_file_get_child (directory, filename);
- g_object_unref (directory);
- g_free (filename);
-
- /* Get the subtitles from that URI */
- full_path_str = g_file_get_uri (full_path);
- g_object_unref (full_path);
- subtitle = uri_get_subtitle_for_uri (full_path_str);
- g_free (full_path_str);
-
- return subtitle;
-}
-
-char *
-uri_get_subtitle_uri (const char *uri)
-{
- GFile *file;
- char *subtitle;
-
- if (g_str_has_prefix (uri, "http") != FALSE)
- return NULL;
-
- /* Has the user specified a subtitle file manually? */
- if (strstr (uri, "#subtitle:") != NULL)
- return NULL;
-
- /* Does the file exist? */
- file = g_file_new_for_uri (uri);
- if (g_file_query_exists (file, NULL) != TRUE) {
- g_object_unref (file);
- return NULL;
- }
-
- /* Try in the current directory */
- subtitle = uri_get_subtitle_for_uri (uri);
- if (subtitle != NULL) {
- g_object_unref (file);
- return subtitle;
- }
-
- subtitle = uri_get_subtitle_in_subdir (file, "subtitles");
- g_object_unref (file);
-
- return subtitle;
-}
-
-/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-#ifndef MAFW_GST_RENDERER_UTILS_H
-#define MAFW_GST_RENDERER_UTILS_H
-
-G_BEGIN_DECLS
-
-gboolean convert_utf8(const gchar *src, gchar **dst);
-gboolean uri_is_playlist(const gchar *uri);
-gboolean uri_is_stream(const gchar *uri);
-
-char *uri_get_subtitle_uri(const char *uri);
-
-G_END_DECLS
-#endif
-/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifndef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME
-
-#include <pulse/pulseaudio.h>
-#include <pulse/glib-mainloop.h>
-#include <pulse/ext-stream-restore.h>
-#include <string.h>
-
-#include "mafw-gst-renderer-worker-volume.h"
-#include "config.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-worker-volume"
-
-#define MAFW_GST_RENDERER_WORKER_VOLUME_SERVER NULL
-
-#define MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PROPERTY "PULSE_PROP_media.role"
-#define MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX "sink-input-by-media-role:"
-#define MAFW_GST_RENDERER_WORKER_VOLUME_ROLE "x-maemo"
-
-#define MAFW_GST_RENDERER_WORKER_SET_TIMEOUT 200
-
-
-struct _MafwGstRendererWorkerVolume {
- pa_glib_mainloop *mainloop;
- pa_context *context;
- gdouble pulse_volume;
- gboolean pulse_mute;
- MafwGstRendererWorkerVolumeChangedCb cb;
- gpointer user_data;
- MafwGstRendererWorkerVolumeMuteCb mute_cb;
- gpointer mute_user_data;
- gdouble current_volume;
- gboolean current_mute;
- gboolean pending_operation;
- gdouble pending_operation_volume;
- gboolean pending_operation_mute;
- guint change_request_id;
- pa_operation *pa_operation;
-};
-
-typedef struct {
- MafwGstRendererWorkerVolume *wvolume;
- MafwGstRendererWorkerVolumeInitCb cb;
- gpointer user_data;
-} InitCbClosure;
-
-#define _pa_volume_to_per_one(volume) \
- ((guint) ((((gdouble)(volume) / (gdouble) PA_VOLUME_NORM) + \
- (gdouble) 0.005) * (gdouble) 100.0) / (gdouble) 100.0)
-#define _pa_volume_from_per_one(volume) \
- ((pa_volume_t)((gdouble)(volume) * (gdouble) PA_VOLUME_NORM))
-
-#define _pa_operation_running(wvolume) \
- (wvolume->pa_operation != NULL && \
- pa_operation_get_state(wvolume->pa_operation) == PA_OPERATION_RUNNING)
-
-static void _state_cb_init(pa_context *c, void *data);
-
-
-static gchar *_get_client_name(void) {
- gchar buf[PATH_MAX];
- gchar *name = NULL;
-
- if (pa_get_binary_name(buf, sizeof(buf)))
- name = g_strdup_printf("mafw-gst-renderer[%s]", buf);
- else
- name = g_strdup("mafw-gst-renderer");
-
- return name;
-}
-
-static void _ext_stream_restore_read_cb(pa_context *c,
- const pa_ext_stream_restore2_info *i,
- int eol,
- void *userdata)
-{
- MafwGstRendererWorkerVolume *wvolume = userdata;
- gdouble volume;
- gboolean mute;
-
- if (eol < 0) {
- g_critical("eol parameter should not be < 1. "
- "Discarding volume event");
- return;
- }
-
- if (i == NULL ||
- strcmp(i->name, MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX
- MAFW_GST_RENDERER_WORKER_VOLUME_ROLE) != 0) {
- return;
- }
-
- volume = _pa_volume_to_per_one(pa_cvolume_max(&i->volume));
- mute = i->mute != 0 ? TRUE : FALSE;
-
- if (_pa_operation_running(wvolume) ||
- (wvolume->pending_operation &&
- (wvolume->pending_operation_volume != volume
-#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
- || wvolume->pending_operation_mute != mute
-#endif
- ))) {
- g_debug("volume notification, but operation running, ignoring");
- return;
- }
-
- wvolume->pulse_volume = volume;
- wvolume->pulse_mute = mute;
-
- /* EMIT VOLUME */
- g_debug("ext stream volume is %lf (mute: %d) for role %s in device %s",
- wvolume->pulse_volume, wvolume->pulse_mute, i->name, i->device);
- if (!wvolume->pending_operation &&
- wvolume->pulse_volume != wvolume->current_volume) {
- wvolume->current_volume = wvolume->pulse_volume;
- if (wvolume->cb != NULL) {
- g_debug("signalling volume");
- wvolume->cb(wvolume, wvolume->current_volume,
- wvolume->user_data);
- }
- }
-#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
- if (!wvolume->pending_operation &&
- wvolume->pulse_mute != wvolume->current_mute) {
- wvolume->current_mute = wvolume->pulse_mute;
- if (wvolume->mute_cb != NULL) {
- g_debug("signalling mute");
- wvolume->mute_cb(wvolume, wvolume->current_mute,
- wvolume->mute_user_data);
- }
- }
-#endif
-
- wvolume->pending_operation = FALSE;
-}
-
-static void _destroy_context(MafwGstRendererWorkerVolume *wvolume)
-{
- if (wvolume->pa_operation != NULL) {
- if (pa_operation_get_state(wvolume->pa_operation) ==
- PA_OPERATION_RUNNING) {
- pa_operation_cancel(wvolume->pa_operation);
- }
- pa_operation_unref(wvolume->pa_operation);
- wvolume->pa_operation = NULL;
- }
- pa_context_unref(wvolume->context);
-}
-
-static InitCbClosure *_init_cb_closure_new(MafwGstRendererWorkerVolume *wvolume,
- MafwGstRendererWorkerVolumeInitCb cb,
- gpointer user_data)
-{
- InitCbClosure *closure;
-
- closure = g_new(InitCbClosure, 1);
- closure->wvolume = wvolume;
- closure->cb = cb;
- closure->user_data = user_data;
-
- return closure;
-}
-
-static void _connect(gpointer user_data)
-{
- gchar *name = NULL;
- pa_mainloop_api *api = NULL;
- InitCbClosure *closure = user_data;
- MafwGstRendererWorkerVolume *wvolume = closure->wvolume;
-
- name = _get_client_name();
-
- /* get the mainloop api and create a context */
- api = pa_glib_mainloop_get_api(wvolume->mainloop);
- wvolume->context = pa_context_new(api, name);
- g_assert(wvolume->context != NULL);
-
- /* register some essential callbacks */
- pa_context_set_state_callback(wvolume->context, _state_cb_init,
- closure);
-
- g_debug("connecting to pulse");
-
- g_assert(pa_context_connect(wvolume->context,
- MAFW_GST_RENDERER_WORKER_VOLUME_SERVER,
- PA_CONTEXT_NOAUTOSPAWN | PA_CONTEXT_NOFAIL,
- NULL) >= 0);
- g_free(name);
-}
-
-static gboolean _reconnect(gpointer user_data)
-{
- InitCbClosure *closure = user_data;
- MafwGstRendererWorkerVolume *wvolume = closure->wvolume;
-
- g_warning("got disconnected from pulse, reconnecting");
- _destroy_context(wvolume);
- _connect(user_data);
-
- return FALSE;
-}
-
-static void
-_state_cb(pa_context *c, void *data)
-{
- MafwGstRendererWorkerVolume *wvolume = data;
- pa_context_state_t state;
-
- state = pa_context_get_state(c);
-
- switch (state) {
- case PA_CONTEXT_TERMINATED:
- case PA_CONTEXT_FAILED:
- {
- InitCbClosure *closure;
-
- closure = _init_cb_closure_new(wvolume, NULL, NULL);
- g_idle_add(_reconnect, closure);
- break;
- }
- case PA_CONTEXT_READY: {
- pa_operation *o;
-
- o = pa_ext_stream_restore2_read(c, _ext_stream_restore_read_cb,
- wvolume);
- g_assert(o != NULL);
- pa_operation_unref(o);
-
- break;
- }
- default:
- break;
- }
-}
-
-static void _ext_stream_restore_read_cb_init(pa_context *c,
- const pa_ext_stream_restore2_info *i,
- int eol,
- void *userdata)
-{
- InitCbClosure *closure = userdata;
-
- if (eol < 0) {
- g_critical("eol parameter should not be < 1");
- }
-
- if (i == NULL ||
- strcmp(i->name, MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX
- MAFW_GST_RENDERER_WORKER_VOLUME_ROLE) != 0)
- return;
-
- closure->wvolume->pulse_volume =
- _pa_volume_to_per_one(pa_cvolume_max(&i->volume));
- closure->wvolume->pulse_mute = i->mute != 0 ? TRUE : FALSE;
- closure->wvolume->current_volume = closure->wvolume->pulse_volume;
- closure->wvolume->current_mute = closure->wvolume->pulse_mute;
-
- /* NOT EMIT VOLUME, BUT DEBUG */
- g_debug("ext stream volume is %lf (mute: %d) for role %s in device %s",
- closure->wvolume->pulse_volume, i->mute, i->name, i->device);
-
- if (closure->cb != NULL) {
- g_debug("initialized: returning volume manager");
- closure->cb(closure->wvolume, closure->user_data);
- } else {
- if (closure->wvolume->cb != NULL) {
- g_debug("signalling volume after reconnection");
- closure->wvolume->cb(closure->wvolume,
- closure->wvolume->current_volume,
- closure->wvolume->user_data);
- }
- if (closure->wvolume->mute_cb != NULL) {
- g_debug("signalling mute after reconnection");
- closure->wvolume->mute_cb(closure->wvolume,
- closure->wvolume->
- current_mute,
- closure->wvolume->
- mute_user_data);
- }
- }
-
- pa_context_set_state_callback(closure->wvolume->context, _state_cb,
- closure->wvolume);
-
- g_free(closure);
-}
-
-static void _ext_stream_restore_subscribe_cb(pa_context *c, void *userdata)
-{
- pa_operation *o;
-
- o = pa_ext_stream_restore2_read(c, _ext_stream_restore_read_cb, userdata);
- g_assert(o != NULL);
- pa_operation_unref(o);
-}
-
-static void
-_state_cb_init(pa_context *c, void *data)
-{
- InitCbClosure *closure = data;
- MafwGstRendererWorkerVolume *wvolume = closure->wvolume;
- pa_context_state_t state;
-
- state = pa_context_get_state(c);
-
- g_debug("state: %d", state);
-
- switch (state) {
- case PA_CONTEXT_TERMINATED:
- case PA_CONTEXT_FAILED:
- g_critical("Connection to pulse failed, reconnection in 1 "
- "second");
- g_timeout_add_seconds(1, _reconnect, closure);
- break;
- case PA_CONTEXT_READY: {
- pa_operation *o;
-
- g_debug("PA_CONTEXT_READY");
-
- o = pa_ext_stream_restore2_read(c,
- _ext_stream_restore_read_cb_init,
- closure);
- g_assert(o != NULL);
- pa_operation_unref(o);
-
- pa_ext_stream_restore_set_subscribe_cb(
- c, _ext_stream_restore_subscribe_cb, wvolume);
-
- o = pa_ext_stream_restore_subscribe(c, 1, NULL, NULL);
- g_assert(o != NULL);
- pa_operation_unref(o);
-
- break;
- }
- default:
- break;
- }
-}
-
-static gboolean _destroy_idle(gpointer data)
-{
- MafwGstRendererWorkerVolume *wvolume = data;
-
- g_debug("destroying");
-
- _destroy_context(wvolume);
- pa_glib_mainloop_free(wvolume->mainloop);
- g_free(wvolume);
-
- return FALSE;
-}
-
-static void
-_state_cb_destroy(pa_context *c, void *data)
-{
- pa_context_state_t state;
-
- state = pa_context_get_state(c);
-
- switch (state) {
- case PA_CONTEXT_TERMINATED:
- g_idle_add(_destroy_idle, data);
- break;
- case PA_CONTEXT_FAILED:
- g_error("Unexpected problem in volume management");
- break;
- default:
- break;
- }
-}
-
-static void _success_cb(pa_context *c, int success, void *userdata)
-{
- if (success == 0) {
- g_critical("Setting volume to pulse operation failed");
- }
-}
-
-static void _remove_set_timeout(MafwGstRendererWorkerVolume *wvolume)
-{
- if (wvolume->change_request_id != 0) {
- g_source_remove(wvolume->change_request_id);
- }
- wvolume->change_request_id = 0;
-}
-
-static gboolean _set_timeout(gpointer data)
-{
- pa_ext_stream_restore2_info info;
- pa_ext_stream_restore2_info *infos[1];
- MafwGstRendererWorkerVolume *wvolume = data;
-
- if (wvolume->pending_operation) {
- g_debug("setting volume ignored as there is still a pending "
- "operation. Waiting till next iteration");
- } else if (wvolume->pulse_volume != wvolume->current_volume
-#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
- || wvolume->pulse_mute != wvolume->current_mute
-#endif
- ) {
-
- info.name = MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX
- MAFW_GST_RENDERER_WORKER_VOLUME_ROLE;
- info.channel_map.channels = 1;
- info.channel_map.map[0] = PA_CHANNEL_POSITION_MONO;
- info.device = NULL;
- info.volume_is_absolute = TRUE;
- infos[0] = &info;
-
- info.mute = wvolume->current_mute;
- pa_cvolume_init(&info.volume);
- pa_cvolume_set(&info.volume, info.channel_map.channels,
- _pa_volume_from_per_one(wvolume->
- current_volume));
-
- g_debug("setting volume to %lf and mute to %d",
- wvolume->current_volume, wvolume->current_mute);
-
- if (wvolume->pa_operation != NULL) {
- pa_operation_unref(wvolume->pa_operation);
- }
-
- wvolume->pending_operation = TRUE;
- wvolume->pending_operation_volume = wvolume->current_volume;
- wvolume->pending_operation_mute = wvolume->current_mute;
-
- wvolume->pa_operation = pa_ext_stream_restore2_write(
- wvolume->context,
- PA_UPDATE_REPLACE,
- (const pa_ext_stream_restore2_info*
- const *)infos,
- 1, TRUE, _success_cb, wvolume);
-
- if (wvolume->pa_operation == NULL) {
- g_critical("NULL operation when writing volume to "
- "pulse");
- _remove_set_timeout(wvolume);
- }
- } else {
- g_debug("removing volume timeout");
- _remove_set_timeout(wvolume);
- }
-
- return wvolume->change_request_id != 0;
-}
-
-void mafw_gst_renderer_worker_volume_init(GMainContext *main_context,
- MafwGstRendererWorkerVolumeInitCb cb,
- gpointer user_data,
- MafwGstRendererWorkerVolumeChangedCb
- changed_cb,
- gpointer changed_user_data,
- MafwGstRendererWorkerVolumeMuteCb
- mute_cb, gpointer mute_user_data)
-{
- MafwGstRendererWorkerVolume *wvolume = NULL;
- InitCbClosure *closure;
-
- g_return_if_fail(cb != NULL);
-
- g_assert(g_setenv(MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PROPERTY,
- MAFW_GST_RENDERER_WORKER_VOLUME_ROLE, FALSE));
-
- g_debug("initializing volume manager");
-
- wvolume = g_new0(MafwGstRendererWorkerVolume, 1);
-
- wvolume->pulse_volume = 1.0;
- wvolume->pulse_mute = FALSE;
- wvolume->cb = changed_cb;
- wvolume->user_data = changed_user_data;
- wvolume->mute_cb = mute_cb;
- wvolume->mute_user_data = mute_user_data;
-
- wvolume->mainloop = pa_glib_mainloop_new(main_context);
- g_assert(wvolume->mainloop != NULL);
-
- closure = _init_cb_closure_new(wvolume, cb, user_data);
- _connect(closure);
-}
-
-void mafw_gst_renderer_worker_volume_set(MafwGstRendererWorkerVolume *wvolume,
- gdouble volume, gboolean mute)
-{
- gboolean signal_volume, signal_mute;
-
- g_return_if_fail(wvolume != NULL);
- g_return_if_fail(pa_context_get_state(wvolume->context) ==
- PA_CONTEXT_READY);
-
-#ifndef MAFW_GST_RENDERER_ENABLE_MUTE
- mute = FALSE;
-#endif
-
- signal_volume = wvolume->current_volume != volume &&
- wvolume->cb != NULL;
- signal_mute = wvolume->current_mute != mute && wvolume->mute_cb != NULL;
-
- wvolume->current_volume = volume;
- wvolume->current_mute = mute;
-
- g_debug("volume set: %lf (mute %d)", volume, mute);
-
- if (signal_volume) {
- g_debug("signalling volume");
- wvolume->cb(wvolume, volume, wvolume->user_data);
- }
-
- if (signal_mute) {
- g_debug("signalling mute");
- wvolume->mute_cb(wvolume, mute, wvolume->mute_user_data);
- }
-
- if ((signal_mute || signal_volume) && wvolume->change_request_id == 0) {
- wvolume->change_request_id =
- g_timeout_add(MAFW_GST_RENDERER_WORKER_SET_TIMEOUT,
- _set_timeout, wvolume);
-
- _set_timeout(wvolume);
- }
-}
-
-gdouble mafw_gst_renderer_worker_volume_get(
- MafwGstRendererWorkerVolume *wvolume)
-{
- g_return_val_if_fail(wvolume != NULL, 0.0);
-
- g_debug("getting volume; %lf", wvolume->current_volume);
-
- return wvolume->current_volume;
-}
-
-gboolean mafw_gst_renderer_worker_volume_is_muted(
- MafwGstRendererWorkerVolume *wvolume)
-{
- g_return_val_if_fail(wvolume != NULL, FALSE);
-
- g_debug("getting mute; %d", wvolume->current_mute);
-
- return wvolume->current_mute;
-}
-
-void mafw_gst_renderer_worker_volume_destroy(
- MafwGstRendererWorkerVolume *wvolume)
-{
- g_return_if_fail(wvolume != NULL);
-
- g_debug("disconnecting");
-
- pa_ext_stream_restore_set_subscribe_cb(wvolume->context, NULL, NULL);
- pa_context_set_state_callback(wvolume->context, _state_cb_destroy,
- wvolume);
- pa_context_disconnect(wvolume->context);
-}
-
-
-
-#else
-
-
-#include "mafw-gst-renderer-worker-volume.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-worker-volume-fake"
-
-struct _MafwGstRendererWorkerVolume {
- MafwGstRendererWorkerVolumeChangedCb cb;
- gpointer user_data;
- MafwGstRendererWorkerVolumeMuteCb mute_cb;
- gpointer mute_user_data;
- gdouble current_volume;
- gboolean current_mute;
-};
-
-typedef struct {
- MafwGstRendererWorkerVolume *wvolume;
- MafwGstRendererWorkerVolumeInitCb cb;
- gpointer user_data;
-} InitCbClosure;
-
-static gboolean _init_cb_closure(gpointer user_data)
-{
- InitCbClosure *closure = user_data;
-
- if (closure->cb != NULL) {
- closure->cb(closure->wvolume, closure->user_data);
- }
- g_free(closure);
-
- return FALSE;
-}
-
-void mafw_gst_renderer_worker_volume_init(GMainContext *main_context,
- MafwGstRendererWorkerVolumeInitCb cb,
- gpointer user_data,
- MafwGstRendererWorkerVolumeChangedCb
- changed_cb,
- gpointer changed_user_data,
- MafwGstRendererWorkerVolumeMuteCb
- mute_cb, gpointer mute_user_data)
-{
- MafwGstRendererWorkerVolume *wvolume = NULL;
- InitCbClosure *closure;
-
- g_return_if_fail(cb != NULL);
-
- g_debug("initializing volume manager");
-
- wvolume = g_new0(MafwGstRendererWorkerVolume, 1);
-
- wvolume->cb = changed_cb;
- wvolume->user_data = changed_user_data;
- wvolume->mute_cb = mute_cb;
- wvolume->mute_user_data = mute_user_data;
- wvolume->current_volume = 0.485;
-
- closure = g_new0(InitCbClosure, 1);
- closure->wvolume = wvolume;
- closure->cb = cb;
- closure->user_data = user_data;
- g_idle_add(_init_cb_closure, closure);
-}
-
-void mafw_gst_renderer_worker_volume_set(MafwGstRendererWorkerVolume *wvolume,
- gdouble volume, gboolean mute)
-{
- gboolean signal_volume, signal_mute;
-
- g_return_if_fail(wvolume != NULL);
-
-#ifndef MAFW_GST_RENDERER_ENABLE_MUTE
- mute = FALSE;
-#endif
-
- signal_volume = wvolume->current_volume != volume &&
- wvolume->cb != NULL;
- signal_mute = wvolume->current_mute != mute && wvolume->mute_cb != NULL;
-
- wvolume->current_volume = volume;
- wvolume->current_mute = mute;
-
- g_debug("volume set: %lf (mute %d)", volume, mute);
-
- if (signal_volume) {
- g_debug("signalling volume");
- wvolume->cb(wvolume, volume, wvolume->user_data);
- }
-
- if (signal_mute) {
- g_debug("signalling mute");
- wvolume->mute_cb(wvolume, mute, wvolume->mute_user_data);
- }
-}
-
-gdouble mafw_gst_renderer_worker_volume_get(
- MafwGstRendererWorkerVolume *wvolume)
-{
- g_return_val_if_fail(wvolume != NULL, 0.0);
-
- g_debug("getting volume; %lf", wvolume->current_volume);
-
- return wvolume->current_volume;
-}
-
-gboolean mafw_gst_renderer_worker_volume_is_muted(
- MafwGstRendererWorkerVolume *wvolume)
-{
- g_return_val_if_fail(wvolume != NULL, FALSE);
-
- g_debug("getting mute; %d", wvolume->current_mute);
-
- return wvolume->current_mute;
-}
-
-void mafw_gst_renderer_worker_volume_destroy(
- MafwGstRendererWorkerVolume *wvolume)
-{
- g_return_if_fail(wvolume != NULL);
-
- g_free(wvolume);
-}
-
-#endif
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef MAFW_GST_RENDERER_WORKER_VOLUME_H
-#define MAFW_GST_RENDERER_WORKER_VOLUME_H
-
-#include <glib.h>
-
-typedef struct _MafwGstRendererWorkerVolume MafwGstRendererWorkerVolume;
-
-typedef void(*MafwGstRendererWorkerVolumeChangedCb)(
- MafwGstRendererWorkerVolume *wvolume, gdouble volume, gpointer data);
-
-typedef void(*MafwGstRendererWorkerVolumeMuteCb)(
- MafwGstRendererWorkerVolume *wvolume, gboolean mute, gpointer data);
-
-typedef void(*MafwGstRendererWorkerVolumeInitCb)(
- MafwGstRendererWorkerVolume *volume, gpointer data);
-
-G_BEGIN_DECLS
-
-void mafw_gst_renderer_worker_volume_init(GMainContext *main_context,
- MafwGstRendererWorkerVolumeInitCb cb,
- gpointer user_data,
- MafwGstRendererWorkerVolumeChangedCb
- changed_cb,
- gpointer changed_user_data,
- MafwGstRendererWorkerVolumeMuteCb
- mute_cb, gpointer mute_user_data);
-
-void mafw_gst_renderer_worker_volume_set(MafwGstRendererWorkerVolume *wvolume,
- gdouble volume, gboolean mute);
-
-gdouble mafw_gst_renderer_worker_volume_get(
- MafwGstRendererWorkerVolume *wvolume);
-gboolean mafw_gst_renderer_worker_volume_is_muted(
- MafwGstRendererWorkerVolume *wvolume);
-
-void mafw_gst_renderer_worker_volume_destroy(
- MafwGstRendererWorkerVolume *wvolume);
-
-G_END_DECLS
-#endif
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <glib.h>
-#include <X11/Xlib.h>
-#include <gst/interfaces/xoverlay.h>
-#include <gst/pbutils/missing-plugins.h>
-#include <gst/base/gstbasesink.h>
-#include <libmafw/mafw.h>
-
-#ifdef HAVE_GDKPIXBUF
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <glib/gstdio.h>
-#include <unistd.h>
-#include "gstscreenshot.h"
-#endif
-
-#include <totem-pl-parser.h>
-#include "mafw-gst-renderer.h"
-#include "mafw-gst-renderer-worker.h"
-#include "mafw-gst-renderer-utils.h"
-#include "blanking.h"
-#include "keypad.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-worker"
-
-#define MAFW_GST_RENDERER_WORKER_SECONDS_READY 60
-#define MAFW_GST_RENDERER_WORKER_SECONDS_DURATION_AND_SEEKABILITY 4
-
-#define MAFW_GST_MISSING_TYPE_DECODER "decoder"
-#define MAFW_GST_MISSING_TYPE_ENCODER "encoder"
-
-#define MAFW_GST_BUFFER_TIME 600000L
-#define MAFW_GST_LATENCY_TIME (MAFW_GST_BUFFER_TIME / 2)
-
-#define NSECONDS_TO_SECONDS(ns) ((ns)%1000000000 < 500000000?\
- GST_TIME_AS_SECONDS((ns)):\
- GST_TIME_AS_SECONDS((ns))+1)
-
-#define _current_metadata_add(worker, key, type, value) \
- do { \
- if (!worker->current_metadata) \
- worker->current_metadata = mafw_metadata_new(); \
- /* At first remove old value */ \
- g_hash_table_remove(worker->current_metadata, key); \
- mafw_metadata_add_something(worker->current_metadata, \
- key, type, 1, value); \
- } while (0)
-
-/* Private variables. */
-/* Global reference to worker instance, needed for Xerror handler */
-static MafwGstRendererWorker *Global_worker = NULL;
-
-/* Forward declarations. */
-static void _do_play(MafwGstRendererWorker *worker);
-static void _do_seek(MafwGstRendererWorker *worker, GstSeekType seek_type,
- gint position, GError **error);
-static void _play_pl_next(MafwGstRendererWorker *worker);
-
-static void _emit_metadatas(MafwGstRendererWorker *worker);
-
-/* Playlist parsing */
-static void _on_pl_entry_parsed(TotemPlParser *parser, gchar *uri,
- gpointer metadata, GSList **plitems)
-{
- if (uri != NULL) {
- *plitems = g_slist_append(*plitems, g_strdup(uri));
- }
-}
-static GSList *_parse_playlist(const gchar *uri)
-{
- static TotemPlParser *pl_parser = NULL;
- GSList *plitems = NULL;
- gulong handler_id;
-
- /* Initialize the playlist parser */
- if (!pl_parser)
- {
- pl_parser = totem_pl_parser_new ();
- g_object_set(pl_parser, "recurse", TRUE, "disable-unsafe",
- TRUE, NULL);
- }
- handler_id = g_signal_connect(G_OBJECT(pl_parser), "entry-parsed",
- G_CALLBACK(_on_pl_entry_parsed), &plitems);
- /* Parsing */
- if (totem_pl_parser_parse(pl_parser, uri, FALSE) !=
- TOTEM_PL_PARSER_RESULT_SUCCESS) {
- /* An error happens while parsing */
-
- }
- g_signal_handler_disconnect(pl_parser, handler_id);
- return plitems;
-}
-
-/*
- * Sends @error to MafwGstRenderer. Only call this from the glib main thread, or
- * face the consequences. @err is free'd.
- */
-static void _send_error(MafwGstRendererWorker *worker, GError *err)
-{
- worker->is_error = TRUE;
- if (worker->notify_error_handler)
- worker->notify_error_handler(worker, worker->owner, err);
- g_error_free(err);
-}
-
-/*
- * Posts an @error on the gst bus. _async_bus_handler will then pick it up and
- * forward to MafwGstRenderer. @err is free'd.
- */
-static void _post_error(MafwGstRendererWorker *worker, GError *err)
-{
- gst_bus_post(worker->bus,
- gst_message_new_error(GST_OBJECT(worker->pipeline),
- err, NULL));
- g_error_free(err);
-}
-
-#ifdef HAVE_GDKPIXBUF
-typedef struct {
- MafwGstRendererWorker *worker;
- gchar *metadata_key;
- GdkPixbuf *pixbuf;
-} SaveGraphicData;
-
-static gchar *_init_tmp_file(void)
-{
- gint fd;
- gchar *path = NULL;
-
- fd = g_file_open_tmp("mafw-gst-renderer-XXXXXX.jpeg", &path, NULL);
- close(fd);
-
- return path;
-}
-
-static void _init_tmp_files_pool(MafwGstRendererWorker *worker)
-{
- guint8 i;
-
- worker->tmp_files_pool_index = 0;
-
- for (i = 0; i < MAFW_GST_RENDERER_MAX_TMP_FILES; i++) {
- worker->tmp_files_pool[i] = NULL;
- }
-}
-
-static void _destroy_tmp_files_pool(MafwGstRendererWorker *worker)
-{
- guint8 i;
-
- for (i = 0; (i < MAFW_GST_RENDERER_MAX_TMP_FILES) &&
- (worker->tmp_files_pool[i] != NULL); i++) {
- g_unlink(worker->tmp_files_pool[i]);
- g_free(worker->tmp_files_pool[i]);
- }
-}
-
-static const gchar *_get_tmp_file_from_pool(
- MafwGstRendererWorker *worker)
-{
- gchar *path = worker->tmp_files_pool[worker->tmp_files_pool_index];
-
- if (path == NULL) {
- path = _init_tmp_file();
- worker->tmp_files_pool[worker->tmp_files_pool_index] = path;
- }
-
- if (++(worker->tmp_files_pool_index) >=
- MAFW_GST_RENDERER_MAX_TMP_FILES) {
- worker->tmp_files_pool_index = 0;
- }
-
- return path;
-}
-
-static void _destroy_pixbuf (guchar *pixbuf, gpointer data)
-{
- gst_buffer_unref(GST_BUFFER(data));
-}
-
-static void _emit_gst_buffer_as_graphic_file_cb(GstBuffer *new_buffer,
- gpointer user_data)
-{
- SaveGraphicData *sgd = user_data;
- GdkPixbuf *pixbuf = NULL;
-
- if (new_buffer != NULL) {
- gint width, height;
- GstStructure *structure;
-
- structure =
- gst_caps_get_structure(GST_BUFFER_CAPS(new_buffer), 0);
-
- gst_structure_get_int(structure, "width", &width);
- gst_structure_get_int(structure, "height", &height);
-
- pixbuf = gdk_pixbuf_new_from_data(
- GST_BUFFER_DATA(new_buffer), GDK_COLORSPACE_RGB,
- FALSE, 8, width, height,
- GST_ROUND_UP_4(3 * width), _destroy_pixbuf,
- new_buffer);
-
- if (sgd->pixbuf != NULL) {
- g_object_unref(sgd->pixbuf);
- sgd->pixbuf = NULL;
- }
- } else {
- pixbuf = sgd->pixbuf;
- }
-
- if (pixbuf != NULL) {
- gboolean save_ok;
- GError *error = NULL;
- const gchar *filename;
-
- filename = _get_tmp_file_from_pool(sgd->worker);
-
- save_ok = gdk_pixbuf_save (pixbuf, filename, "jpeg", &error,
- NULL);
-
- g_object_unref (pixbuf);
-
- if (save_ok) {
- /* Add the info to the current metadata. */
- _current_metadata_add(sgd->worker, sgd->metadata_key,
- G_TYPE_STRING,
- (gchar*)filename);
-
- /* Emit the metadata. */
- mafw_renderer_emit_metadata_string(sgd->worker->owner,
- sgd->metadata_key,
- (gchar *) filename);
- } else {
- if (error != NULL) {
- g_warning ("%s\n", error->message);
- g_error_free (error);
- } else {
- g_critical("Unknown error when saving pixbuf "
- "with GStreamer data");
- }
- }
- } else {
- g_warning("Could not create pixbuf from GstBuffer");
- }
-
- g_free(sgd->metadata_key);
- g_free(sgd);
-}
-
-static void _pixbuf_size_prepared_cb (GdkPixbufLoader *loader,
- gint width, gint height,
- gpointer user_data)
-{
- /* Be sure the image size is reasonable */
- if (width > 512 || height > 512) {
- g_debug ("pixbuf: image is too big: %dx%d", width, height);
- gdouble ar;
- ar = (gdouble) width / height;
- if (width > height) {
- width = 512;
- height = width / ar;
- } else {
- height = 512;
- width = height * ar;
- }
- g_debug ("pixbuf: scaled image to %dx%d", width, height);
- gdk_pixbuf_loader_set_size (loader, width, height);
- }
-}
-
-static void _emit_gst_buffer_as_graphic_file(MafwGstRendererWorker *worker,
- GstBuffer *buffer,
- const gchar *metadata_key)
-{
- GdkPixbufLoader *loader;
- GstStructure *structure;
- const gchar *mime = NULL;
- GError *error = NULL;
-
- g_return_if_fail((buffer != NULL) && GST_IS_BUFFER(buffer));
-
- structure = gst_caps_get_structure(GST_BUFFER_CAPS(buffer), 0);
- mime = gst_structure_get_name(structure);
-
- if (g_str_has_prefix(mime, "video/x-raw")) {
- gint framerate_d, framerate_n;
- GstCaps *to_caps;
- SaveGraphicData *sgd;
-
- gst_structure_get_fraction (structure, "framerate",
- &framerate_n, &framerate_d);
-
- to_caps = gst_caps_new_simple ("video/x-raw-rgb",
- "bpp", G_TYPE_INT, 24,
- "depth", G_TYPE_INT, 24,
- "framerate", GST_TYPE_FRACTION,
- framerate_n, framerate_d,
- "pixel-aspect-ratio",
- GST_TYPE_FRACTION, 1, 1,
- "endianness",
- G_TYPE_INT, G_BIG_ENDIAN,
- "red_mask", G_TYPE_INT,
- 0xff0000,
- "green_mask",
- G_TYPE_INT, 0x00ff00,
- "blue_mask",
- G_TYPE_INT, 0x0000ff,
- NULL);
-
- sgd = g_new0(SaveGraphicData, 1);
- sgd->worker = worker;
- sgd->metadata_key = g_strdup(metadata_key);
-
- g_debug("pixbuf: using bvw to convert image format");
- bvw_frame_conv_convert (buffer, to_caps,
- _emit_gst_buffer_as_graphic_file_cb,
- sgd);
- } else {
- GdkPixbuf *pixbuf = NULL;
- loader = gdk_pixbuf_loader_new_with_mime_type(mime, &error);
- g_signal_connect (G_OBJECT (loader), "size-prepared",
- (GCallback)_pixbuf_size_prepared_cb, NULL);
-
- if (loader == NULL) {
- g_warning ("%s\n", error->message);
- g_error_free (error);
- } else {
- if (!gdk_pixbuf_loader_write (loader,
- GST_BUFFER_DATA(buffer),
- GST_BUFFER_SIZE(buffer),
- &error)) {
- g_warning ("%s\n", error->message);
- g_error_free (error);
-
- gdk_pixbuf_loader_close (loader, NULL);
- } else {
- pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
-
- if (!gdk_pixbuf_loader_close (loader, &error)) {
- g_warning ("%s\n", error->message);
- g_error_free (error);
-
- g_object_unref(pixbuf);
- } else {
- SaveGraphicData *sgd;
-
- sgd = g_new0(SaveGraphicData, 1);
-
- sgd->worker = worker;
- sgd->metadata_key =
- g_strdup(metadata_key);
- sgd->pixbuf = pixbuf;
-
- _emit_gst_buffer_as_graphic_file_cb(
- NULL, sgd);
- }
- }
- g_object_unref(loader);
- }
- }
-}
-#endif
-
-static gboolean _go_to_gst_ready(gpointer user_data)
-{
- MafwGstRendererWorker *worker = user_data;
-
- g_return_val_if_fail(worker->state == GST_STATE_PAUSED ||
- worker->prerolling, FALSE);
-
- worker->seek_position =
- mafw_gst_renderer_worker_get_position(worker);
-
- g_debug("going to GST_STATE_READY");
- gst_element_set_state(worker->pipeline, GST_STATE_READY);
- worker->in_ready = TRUE;
- worker->ready_timeout = 0;
-
- return FALSE;
-}
-
-static void _add_ready_timeout(MafwGstRendererWorker *worker)
-{
- if (worker->media.seekable) {
- if (!worker->ready_timeout)
- {
- g_debug("Adding timeout to go to GST_STATE_READY");
- worker->ready_timeout =
- g_timeout_add_seconds(
- MAFW_GST_RENDERER_WORKER_SECONDS_READY,
- _go_to_gst_ready,
- worker);
- }
- } else {
- g_debug("Not adding timeout to go to GST_STATE_READY as media "
- "is not seekable");
- worker->ready_timeout = 0;
- }
-}
-
-static void _remove_ready_timeout(MafwGstRendererWorker *worker)
-{
- if (worker->ready_timeout != 0) {
- g_debug("removing timeout for READY");
- g_source_remove(worker->ready_timeout);
- worker->ready_timeout = 0;
- }
- worker->in_ready = FALSE;
-}
-
-static gboolean _emit_video_info(MafwGstRendererWorker *worker)
-{
- mafw_renderer_emit_metadata_int(worker->owner,
- MAFW_METADATA_KEY_RES_X,
- worker->media.video_width);
- mafw_renderer_emit_metadata_int(worker->owner,
- MAFW_METADATA_KEY_RES_Y,
- worker->media.video_height);
- mafw_renderer_emit_metadata_double(worker->owner,
- MAFW_METADATA_KEY_VIDEO_FRAMERATE,
- worker->media.fps);
- return FALSE;
-}
-
-/*
- * Checks if the video details are supported. It also extracts other useful
- * information (such as PAR and framerate) from the caps, if available. NOTE:
- * this will be called from a different thread than glib's mainloop (when
- * invoked via _stream_info_cb); don't call MafwGstRenderer directly.
- *
- * Returns: TRUE if video details are acceptable.
- */
-static gboolean _handle_video_info(MafwGstRendererWorker *worker,
- const GstStructure *structure)
-{
- gint width, height;
- gdouble fps;
-
- width = height = 0;
- gst_structure_get_int(structure, "width", &width);
- gst_structure_get_int(structure, "height", &height);
- g_debug("video size: %d x %d", width, height);
- if (gst_structure_has_field(structure, "pixel-aspect-ratio"))
- {
- gst_structure_get_fraction(structure, "pixel-aspect-ratio",
- &worker->media.par_n,
- &worker->media.par_d);
- g_debug("video PAR: %d:%d", worker->media.par_n,
- worker->media.par_d);
- width = width * worker->media.par_n / worker->media.par_d;
- }
-
- fps = 1.0;
- if (gst_structure_has_field(structure, "framerate"))
- {
- gint fps_n, fps_d;
-
- gst_structure_get_fraction(structure, "framerate",
- &fps_n, &fps_d);
- if (fps_d > 0)
- fps = (gdouble)fps_n / (gdouble)fps_d;
- g_debug("video fps: %f", fps);
- }
-
- worker->media.video_width = width;
- worker->media.video_height = height;
- worker->media.fps = fps;
-
- /* Add the info to the current metadata. */
- gint p_width, p_height, p_fps;
-
- p_width = width;
- p_height = height;
- p_fps = fps;
-
- _current_metadata_add(worker, MAFW_METADATA_KEY_RES_X, G_TYPE_INT,
- p_width);
- _current_metadata_add(worker, MAFW_METADATA_KEY_RES_Y, G_TYPE_INT,
- p_height);
- _current_metadata_add(worker, MAFW_METADATA_KEY_VIDEO_FRAMERATE,
- G_TYPE_DOUBLE,
- p_fps);
-
- /* Emit the metadata.*/
- g_idle_add((GSourceFunc)_emit_video_info, worker);
-
- return TRUE;
-}
-
-static void _parse_stream_info_item(MafwGstRendererWorker *worker, GObject *obj)
-{
- GParamSpec *pspec;
- GEnumValue *val;
- gint type;
-
- g_object_get(obj, "type", &type, NULL);
- pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), "type");
- val = g_enum_get_value(G_PARAM_SPEC_ENUM(pspec)->enum_class, type);
- if (!val)
- return;
- if (!g_ascii_strcasecmp(val->value_nick, "video") ||
- !g_ascii_strcasecmp(val->value_name, "video"))
- {
- GstCaps *vcaps;
- GstObject *object;
-
- object = NULL;
- g_object_get(obj, "object", &object, NULL);
- vcaps = NULL;
- if (object) {
- vcaps = gst_pad_get_caps(GST_PAD_CAST(object));
- } else {
- g_object_get(obj, "caps", &vcaps, NULL);
- gst_caps_ref(vcaps);
- }
- if (vcaps) {
- if (gst_caps_is_fixed(vcaps))
- {
- _handle_video_info(
- worker,
- gst_caps_get_structure(vcaps, 0));
- }
- gst_caps_unref(vcaps);
- }
- }
-}
-
-/* It always returns FALSE, because it is used as an idle callback as well. */
-static gboolean _parse_stream_info(MafwGstRendererWorker *worker)
-{
- GList *stream_info, *s;
-
- stream_info = NULL;
- if (g_object_class_find_property(G_OBJECT_GET_CLASS(worker->pipeline),
- "stream-info"))
- {
- g_object_get(worker->pipeline,
- "stream-info", &stream_info, NULL);
- }
- for (s = stream_info; s; s = g_list_next(s))
- _parse_stream_info_item(worker, G_OBJECT(s->data));
- return FALSE;
-}
-
-static void mafw_gst_renderer_worker_apply_xid(MafwGstRendererWorker *worker)
-{
- /* Set sink to render on the provided XID if we have do have
- a XID a valid video sink and we are rendeing video content */
- if (worker->xid &&
- worker->vsink &&
- worker->media.has_visual_content)
- {
- g_debug ("Setting overlay, window id: %x",
- (gint) worker->xid);
- gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(worker->vsink),
- worker->xid);
- /* Ask the gst to redraw the frame if we are paused */
- /* TODO: in MTG this works only in non-fs -> fs way. */
- if (worker->state == GST_STATE_PAUSED)
- {
- gst_x_overlay_expose(GST_X_OVERLAY(worker->vsink));
- }
- } else {
- g_debug("Not setting overlay for window id: %x",
- (gint) worker->xid);
- }
-}
-
-/*
- * GstBus synchronous message handler. NOTE that this handler is NOT invoked
- * from the glib thread, so be careful what you do here.
- */
-static GstBusSyncReply _sync_bus_handler(GstBus *bus, GstMessage *msg,
- MafwGstRendererWorker *worker)
-{
- if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ELEMENT &&
- gst_structure_has_name(msg->structure, "prepare-xwindow-id"))
- {
- g_debug("got prepare-xwindow-id");
- worker->media.has_visual_content = TRUE;
- /* The user has to preset the XID, we don't create windows by
- * ourselves. */
- if (!worker->xid) {
- /* We must post an error message to the bus that will
- * be picked up by _async_bus_handler. Calling the
- * notification function directly from here (different
- * thread) is not healthy. */
- g_warning("No video window set!");
- _post_error(worker,
- g_error_new_literal(
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_PLAYBACK,
- "No video window XID set"));
- gst_message_unref (msg);
- return GST_BUS_DROP;
- } else {
- g_debug ("Video window to use is: %x",
- (gint) worker->xid);
- }
-
- /* Instruct vsink to use the client-provided window */
- mafw_gst_renderer_worker_apply_xid(worker);
-
- /* Handle colorkey and autopaint */
- mafw_gst_renderer_worker_set_autopaint(
- worker,
- worker->autopaint);
- if (worker->colorkey == -1)
- g_object_get(worker->vsink,
- "colorkey", &worker->colorkey, NULL);
- else
- mafw_gst_renderer_worker_set_colorkey(
- worker,
- worker->colorkey);
- /* Defer the signal emission to the thread running the
- * mainloop. */
- if (worker->colorkey != -1) {
- gst_bus_post(worker->bus,
- gst_message_new_application(
- GST_OBJECT(worker->vsink),
- gst_structure_empty_new("ckey")));
- }
- gst_message_unref (msg);
- return GST_BUS_DROP;
- }
- /* do not unref message when returning PASS */
- return GST_BUS_PASS;
-}
-
-static void _free_taglist_item(GstMessage *msg, gpointer data)
-{
- gst_message_unref(msg);
-}
-
-static void _free_taglist(MafwGstRendererWorker *worker)
-{
- if (worker->tag_list != NULL)
- {
- g_ptr_array_foreach(worker->tag_list, (GFunc)_free_taglist_item,
- NULL);
- g_ptr_array_free(worker->tag_list, TRUE);
- worker->tag_list = NULL;
- }
-}
-
-static gboolean _seconds_duration_equal(gint64 duration1, gint64 duration2)
-{
- gint64 duration1_seconds, duration2_seconds;
-
- duration1_seconds = NSECONDS_TO_SECONDS(duration1);
- duration2_seconds = NSECONDS_TO_SECONDS(duration2);
-
- return duration1_seconds == duration2_seconds;
-}
-
-static void _check_duration(MafwGstRendererWorker *worker, gint64 value)
-{
- MafwGstRenderer *renderer = worker->owner;
- gboolean right_query = TRUE;
-
- if (value == -1) {
- GstFormat format = GST_FORMAT_TIME;
- right_query =
- gst_element_query_duration(worker->pipeline, &format,
- &value);
- }
-
- if (right_query && value > 0) {
- gint duration_seconds = NSECONDS_TO_SECONDS(value);
-
- if (!_seconds_duration_equal(worker->media.length_nanos,
- value)) {
- /* Add the duration to the current metadata. */
- _current_metadata_add(worker, MAFW_METADATA_KEY_DURATION,
- G_TYPE_INT64,
- (gint64)duration_seconds);
- /* Emit the duration. */
- mafw_renderer_emit_metadata_int64(
- worker->owner, MAFW_METADATA_KEY_DURATION,
- (gint64)duration_seconds);
- }
-
- /* We compare this duration we just got with the
- * source one and update it in the source if needed */
- if (duration_seconds > 0 &&
- duration_seconds != renderer->media->duration) {
- mafw_gst_renderer_update_source_duration(
- renderer,
- duration_seconds);
- }
- }
-
- worker->media.length_nanos = value;
- g_debug("media duration: %lld", worker->media.length_nanos);
-}
-
-static void _check_seekability(MafwGstRendererWorker *worker)
-{
- MafwGstRenderer *renderer = worker->owner;
- SeekabilityType seekable = SEEKABILITY_NO_SEEKABLE;
-
- if (worker->media.length_nanos != -1)
- {
- g_debug("source seekability %d", renderer->media->seekability);
-
- if (renderer->media->seekability != SEEKABILITY_NO_SEEKABLE) {
- g_debug("Quering GStreamer for seekability");
- GstQuery *seek_query;
- GstFormat format = GST_FORMAT_TIME;
- /* Query the seekability of the stream */
- seek_query = gst_query_new_seeking(format);
- if (gst_element_query(worker->pipeline, seek_query)) {
- gboolean renderer_seekable = FALSE;
- gst_query_parse_seeking(seek_query, NULL,
- &renderer_seekable,
- NULL, NULL);
- g_debug("GStreamer seekability %d",
- renderer_seekable);
- seekable = renderer_seekable ?
- SEEKABILITY_SEEKABLE :
- SEEKABILITY_NO_SEEKABLE;
- }
- gst_query_unref(seek_query);
- }
- }
-
- if (worker->media.seekable != seekable) {
- gboolean is_seekable = (seekable == SEEKABILITY_SEEKABLE);
-
- /* Add the seekability to the current metadata. */
- _current_metadata_add(worker, MAFW_METADATA_KEY_IS_SEEKABLE,
- G_TYPE_BOOLEAN, is_seekable);
-
- /* Emit. */
- mafw_renderer_emit_metadata_boolean(
- worker->owner, MAFW_METADATA_KEY_IS_SEEKABLE,
- is_seekable);
- }
-
- g_debug("media seekable: %d", seekable);
- worker->media.seekable = seekable;
-}
-
-static gboolean _query_duration_and_seekability_timeout(gpointer data)
-{
- MafwGstRendererWorker *worker = data;
-
- _check_duration(worker, -1);
- _check_seekability(worker);
-
- worker->duration_seek_timeout = 0;
-
- return FALSE;
-}
-
-/*
- * Called when the pipeline transitions into PAUSED state. It extracts more
- * information from Gst.
- */
-static void _finalize_startup(MafwGstRendererWorker *worker)
-{
- /* Check video caps */
- if (worker->media.has_visual_content) {
- GstPad *pad = GST_BASE_SINK_PAD(worker->vsink);
- GstCaps *caps = GST_PAD_CAPS(pad);
- if (caps && gst_caps_is_fixed(caps)) {
- GstStructure *structure;
- structure = gst_caps_get_structure(caps, 0);
- if (!_handle_video_info(worker, structure))
- return;
- }
- }
-
- /* Something might have gone wrong at this point already. */
- if (worker->is_error) {
- g_debug("Error occured during preroll");
- return;
- }
-
- /* Streaminfo might reveal the media to be unsupported. Therefore we
- * need to check the error again. */
- _parse_stream_info(worker);
- if (worker->is_error) {
- g_debug("Error occured. Leaving");
- return;
- }
-
- /* Check duration and seekability */
- if (worker->duration_seek_timeout != 0) {
- g_source_remove(worker->duration_seek_timeout);
- worker->duration_seek_timeout = 0;
- }
- _check_duration(worker, -1);
- _check_seekability(worker);
-}
-
-static void _add_duration_seek_query_timeout(MafwGstRendererWorker *worker)
-{
- if (worker->duration_seek_timeout != 0) {
- g_source_remove(worker->duration_seek_timeout);
- }
- worker->duration_seek_timeout = g_timeout_add_seconds(
- MAFW_GST_RENDERER_WORKER_SECONDS_DURATION_AND_SEEKABILITY,
- _query_duration_and_seekability_timeout,
- worker);
-}
-
-static void _do_pause_postprocessing(MafwGstRendererWorker *worker)
-{
- if (worker->notify_pause_handler) {
- worker->notify_pause_handler(worker, worker->owner);
- }
-
-#ifdef HAVE_GDKPIXBUF
- if (worker->media.has_visual_content &&
- worker->current_frame_on_pause) {
- GstBuffer *buffer = NULL;
-
- g_object_get(worker->pipeline, "frame", &buffer, NULL);
-
- if (buffer != NULL) {
- _emit_gst_buffer_as_graphic_file(
- worker, buffer,
- MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI);
- }
- }
-#endif
-
- _add_ready_timeout(worker);
-}
-
-static void _report_playing_state(MafwGstRendererWorker * worker)
-{
- if (worker->report_statechanges) {
- switch (worker->mode) {
- case WORKER_MODE_SINGLE_PLAY:
- /* Notify play if we are playing in
- * single mode */
- if (worker->notify_play_handler)
- worker->notify_play_handler(
- worker,
- worker->owner);
- break;
- case WORKER_MODE_PLAYLIST:
- case WORKER_MODE_REDUNDANT:
- /* Only notify play when the "playlist"
- playback starts, don't notify play for each
- individual element of the playlist. */
- if (worker->pl.notify_play_pending) {
- if (worker->notify_play_handler)
- worker->notify_play_handler(
- worker,
- worker->owner);
- worker->pl.notify_play_pending = FALSE;
- }
- break;
- default: break;
- }
- }
-}
-
-static void _handle_state_changed(GstMessage *msg, MafwGstRendererWorker *worker)
-{
- GstState newstate, oldstate;
- GstStateChange statetrans;
- MafwGstRenderer *renderer = (MafwGstRenderer*)worker->owner;
-
- gst_message_parse_state_changed(msg, &oldstate, &newstate, NULL);
- statetrans = GST_STATE_TRANSITION(oldstate, newstate);
- g_debug ("State changed: %d: %d -> %d", worker->state, oldstate, newstate);
-
- /* If the state is the same we do nothing, otherwise, we keep
- * it */
- if (worker->state == newstate) {
- return;
- } else {
- worker->state = newstate;
- }
-
- if (statetrans == GST_STATE_CHANGE_READY_TO_PAUSED &&
- worker->in_ready) {
- /* Woken up from READY, resume stream position and playback */
- g_debug("State changed to pause after ready");
- if (worker->seek_position > 0) {
- _check_seekability(worker);
- if (worker->media.seekable) {
- g_debug("performing a seek");
- _do_seek(worker, GST_SEEK_TYPE_SET,
- worker->seek_position, NULL);
- } else {
- g_critical("media is not seekable (and should)");
- }
- }
-
- /* If playing a stream wait for buffering to finish before
- starting to play */
- if (!worker->is_stream || worker->is_live) {
- _do_play(worker);
- }
- return;
- }
-
- /* While buffering, we have to wait in PAUSED
- until we reach 100% before doing anything */
- if (worker->buffering) {
- if (statetrans == GST_STATE_CHANGE_PAUSED_TO_PLAYING) {
- /* Mmm... probably the client issued a seek on the
- * stream and then a play/resume command right away,
- * so the stream got into PLAYING state while
- * buffering. When the next buffering signal arrives,
- * the stream will be PAUSED silently and resumed when
- * buffering is done (silently too), so let's signal
- * the state change to PLAYING here. */
- _report_playing_state(worker);
- }
- return;
- }
-
- switch (statetrans) {
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- if (worker->prerolling && worker->report_statechanges) {
- /* PAUSED after pipeline has been
- * constructed. We check caps, seek and
- * duration and if staying in pause is needed,
- * we perform operations for pausing, such as
- * current frame on pause and signalling state
- * change and adding the timeout to go to ready */
- g_debug ("Prerolling done, finalizaing startup");
- _finalize_startup(worker);
- _do_play(worker);
- renderer->play_failed_count = 0;
-
- if (worker->stay_paused) {
- _do_pause_postprocessing(worker);
- }
- worker->prerolling = FALSE;
- }
- break;
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- /* When pausing we do the stuff, like signalling
- * state, current frame on pause and timeout to go to
- * ready */
- if (worker->report_statechanges) {
- _do_pause_postprocessing(worker);
- }
- break;
- case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- /* if seek was called, at this point it is really ended */
- worker->seek_position = -1;
- worker->eos = FALSE;
-
- /* Signal state change if needed */
- _report_playing_state(worker);
-
- /* Prevent blanking if we are playing video */
- if (worker->media.has_visual_content) {
- blanking_prohibit();
- }
- keypadlocking_prohibit();
- /* Remove the ready timeout if we are playing [again] */
- _remove_ready_timeout(worker);
- /* If mode is redundant we are trying to play one of several
- * candidates, so when we get a successful playback, we notify
- * the real URI that we are playing */
- if (worker->mode == WORKER_MODE_REDUNDANT) {
- mafw_renderer_emit_metadata_string(
- worker->owner,
- MAFW_METADATA_KEY_URI,
- worker->media.location);
- }
-
- /* Emit metadata. We wait until we reach the playing
- state because this speeds up playback start time */
- _emit_metadatas(worker);
- /* Query duration and seekability. Useful for vbr
- * clips or streams. */
- _add_duration_seek_query_timeout(worker);
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- /* If we went to READY, we free the taglist and
- * deassign the timout it */
- if (worker->in_ready) {
- g_debug("changed to GST_STATE_READY");
- _free_taglist(worker);
- }
- break;
- default:
- break;
- }
-}
-
-static void _handle_duration(MafwGstRendererWorker *worker, GstMessage *msg)
-{
- GstFormat fmt;
- gint64 duration;
-
- gst_message_parse_duration(msg, &fmt, &duration);
-
- if (worker->duration_seek_timeout != 0) {
- g_source_remove(worker->duration_seek_timeout);
- worker->duration_seek_timeout = 0;
- }
-
- _check_duration(worker,
- duration != GST_CLOCK_TIME_NONE ? duration : -1);
- _check_seekability(worker);
-}
-
-#ifdef HAVE_GDKPIXBUF
-static void _emit_renderer_art(MafwGstRendererWorker *worker,
- const GstTagList *list)
-{
- GstBuffer *buffer = NULL;
- const GValue *value = NULL;
-
- g_return_if_fail(gst_tag_list_get_tag_size(list, GST_TAG_IMAGE) > 0);
-
- value = gst_tag_list_get_value_index(list, GST_TAG_IMAGE, 0);
-
- g_return_if_fail((value != NULL) && G_VALUE_HOLDS(value, GST_TYPE_BUFFER));
-
- buffer = g_value_peek_pointer(value);
-
- g_return_if_fail((buffer != NULL) && GST_IS_BUFFER(buffer));
-
- _emit_gst_buffer_as_graphic_file(worker, buffer,
- MAFW_METADATA_KEY_RENDERER_ART_URI);
-}
-#endif
-
-static GHashTable* _build_tagmap(void)
-{
- GHashTable *hash_table = NULL;
-
- hash_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
- g_free);
-
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_TITLE),
- g_strdup(MAFW_METADATA_KEY_TITLE));
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_ARTIST),
- g_strdup(MAFW_METADATA_KEY_ARTIST));
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_AUDIO_CODEC),
- g_strdup(MAFW_METADATA_KEY_AUDIO_CODEC));
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_VIDEO_CODEC),
- g_strdup(MAFW_METADATA_KEY_VIDEO_CODEC));
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_BITRATE),
- g_strdup(MAFW_METADATA_KEY_BITRATE));
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_LANGUAGE_CODE),
- g_strdup(MAFW_METADATA_KEY_ENCODING));
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_ALBUM),
- g_strdup(MAFW_METADATA_KEY_ALBUM));
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_GENRE),
- g_strdup(MAFW_METADATA_KEY_GENRE));
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_TRACK_NUMBER),
- g_strdup(MAFW_METADATA_KEY_TRACK));
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_ORGANIZATION),
- g_strdup(MAFW_METADATA_KEY_ORGANIZATION));
-#ifdef HAVE_GDKPIXBUF
- g_hash_table_insert(hash_table, g_strdup(GST_TAG_IMAGE),
- g_strdup(MAFW_METADATA_KEY_RENDERER_ART_URI));
-#endif
-
- return hash_table;
-}
-
-/*
- * Emits metadata-changed signals for gst tags.
- */
-static void _emit_tag(const GstTagList *list, const gchar *tag,
- MafwGstRendererWorker *worker)
-{
- /* Mapping between Gst <-> MAFW metadata tags
- * NOTE: This assumes that GTypes matches between GST and MAFW. */
- static GHashTable *tagmap = NULL;
- gint i, count;
- const gchar *mafwtag;
- GType type;
- GValueArray *values;
-
- if (tagmap == NULL) {
- tagmap = _build_tagmap();
- }
-
- g_debug("tag: '%s' (type: %s)", tag,
- g_type_name(gst_tag_get_type(tag)));
- /* Is there a mapping for this tag? */
- mafwtag = g_hash_table_lookup(tagmap, tag);
- if (!mafwtag)
- return;
-
-#ifdef HAVE_GDKPIXBUF
- if (strcmp (mafwtag, MAFW_METADATA_KEY_RENDERER_ART_URI) == 0) {
- _emit_renderer_art(worker, list);
- return;
- }
-#endif
-
- /* Build a value array of this tag. We need to make sure that strings
- * are UTF-8. GstTagList API says that the value is always UTF8, but it
- * looks like the ID3 demuxer still might sometimes produce non-UTF-8
- * strings. */
- count = gst_tag_list_get_tag_size(list, tag);
- type = gst_tag_get_type(tag);
- values = g_value_array_new(count);
- for (i = 0; i < count; ++i) {
- GValue *v = (GValue *)
- gst_tag_list_get_value_index(list, tag, i);
- if (type == G_TYPE_STRING) {
- gchar *orig, *utf8;
-
- gst_tag_list_get_string_index(list, tag, i, &orig);
- if (convert_utf8(orig, &utf8)) {
- GValue utf8gval = {0};
-
- g_value_init(&utf8gval, G_TYPE_STRING);
- g_value_take_string(&utf8gval, utf8);
- _current_metadata_add(worker, mafwtag, G_TYPE_STRING,
- utf8);
- g_value_array_append(values, &utf8gval);
- g_value_unset(&utf8gval);
- }
- g_free(orig);
- } else if (type == G_TYPE_UINT) {
- GValue intgval = {0};
- gint intval;
-
- g_value_init(&intgval, G_TYPE_INT);
- g_value_transform(v, &intgval);
- intval = g_value_get_int(&intgval);
- _current_metadata_add(worker, mafwtag, G_TYPE_INT,
- intval);
- g_value_array_append(values, &intgval);
- g_value_unset(&intgval);
- } else {
- _current_metadata_add(worker, mafwtag, G_TYPE_VALUE,
- v);
- g_value_array_append(values, v);
- }
- }
-
- /* Emit the metadata. */
- g_signal_emit_by_name(worker->owner, "metadata-changed", mafwtag,
- values);
-
- g_value_array_free(values);
-}
-
-/**
- * Collect tag-messages, parse it later, when playing is ongoing
- */
-static void _handle_tag(MafwGstRendererWorker *worker, GstMessage *msg)
-{
- /* Do not emit metadata until we get to PLAYING state to speed up
- playback start */
- if (worker->tag_list == NULL)
- worker->tag_list = g_ptr_array_new();
- g_ptr_array_add(worker->tag_list, gst_message_ref(msg));
-
- /* Some tags come in playing state, so in this case we have
- to emit them right away (example: radio stations) */
- if (worker->state == GST_STATE_PLAYING) {
- _emit_metadatas(worker);
- }
-}
-
-/**
- * Parses the list of tag-messages
- */
-static void _parse_tagmsg(GstMessage *msg, MafwGstRendererWorker *worker)
-{
- GstTagList *new_tags;
-
- gst_message_parse_tag(msg, &new_tags);
- gst_tag_list_foreach(new_tags, (gpointer)_emit_tag, worker);
- gst_tag_list_free(new_tags);
- gst_message_unref(msg);
-}
-
-/**
- * Parses the collected tag messages, and emits the metadatas
- */
-static void _emit_metadatas(MafwGstRendererWorker *worker)
-{
- if (worker->tag_list != NULL)
- {
- g_ptr_array_foreach(worker->tag_list, (GFunc)_parse_tagmsg,
- worker);
- g_ptr_array_free(worker->tag_list, TRUE);
- worker->tag_list = NULL;
- }
-}
-
-static void _reset_volume_and_mute_to_pipeline(MafwGstRendererWorker *worker)
-{
-#ifdef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME
- g_debug("resetting volume and mute to pipeline");
-
- if (worker->pipeline != NULL) {
- g_object_set(
- G_OBJECT(worker->pipeline), "volume",
- mafw_gst_renderer_worker_volume_get(worker->wvolume),
- "mute",
- mafw_gst_renderer_worker_volume_is_muted(worker->wvolume),
- NULL);
- }
-#endif
-}
-
-static void _handle_buffering(MafwGstRendererWorker *worker, GstMessage *msg)
-{
- gint percent;
- MafwGstRenderer *renderer = (MafwGstRenderer*)worker->owner;
-
- gst_message_parse_buffering(msg, &percent);
- g_debug("buffering: %d", percent);
-
- /* No state management needed for live pipelines */
- if (!worker->is_live) {
- worker->buffering = TRUE;
- if (percent < 100 && worker->state == GST_STATE_PLAYING) {
- g_debug("setting pipeline to PAUSED not to wolf the "
- "buffer down");
- worker->report_statechanges = FALSE;
- /* We can't call _pause() here, since it sets
- * the "report_statechanges" to TRUE. We don't
- * want that, application doesn't need to know
- * that internally the state changed to
- * PAUSED. */
- if (gst_element_set_state(worker->pipeline,
- GST_STATE_PAUSED) ==
- GST_STATE_CHANGE_ASYNC)
- {
- /* XXX this blocks at most 2 seconds. */
- gst_element_get_state(worker->pipeline, NULL,
- NULL,
- 2 * GST_SECOND);
- }
- }
-
- if (percent >= 100) {
- /* On buffering we go to PAUSED, so here we move back to
- PLAYING */
- worker->buffering = FALSE;
- if (worker->state == GST_STATE_PAUSED) {
- /* If buffering more than once, do this only the
- first time we are done with buffering */
- if (worker->prerolling) {
- g_debug("buffering concluded during "
- "prerolling");
- _finalize_startup(worker);
- _do_play(worker);
- renderer->play_failed_count = 0;
- /* Send the paused notification */
- if (worker->stay_paused &&
- worker->notify_pause_handler) {
- worker->notify_pause_handler(
- worker,
- worker->owner);
- }
- worker->prerolling = FALSE;
- } else if (worker->in_ready) {
- /* If we had been woken up from READY
- and we have finish our buffering,
- check if we have to play or stay
- paused and if we have to play,
- signal the state change. */
- g_debug("buffering concluded, "
- "continuing playing");
- _do_play(worker);
- } else if (!worker->stay_paused) {
- /* This means, that we were playing but
- ran out of buffer, so we silently
- paused waited for buffering to
- finish and now we continue silently
- (silently meaning we do not expose
- state changes) */
- g_debug("buffering concluded, setting "
- "pipeline to PLAYING again");
- _reset_volume_and_mute_to_pipeline(
- worker);
- if (gst_element_set_state(
- worker->pipeline,
- GST_STATE_PLAYING) ==
- GST_STATE_CHANGE_ASYNC)
- {
- /* XXX this blocks at most 2 seconds. */
- gst_element_get_state(
- worker->pipeline, NULL, NULL,
- 2 * GST_SECOND);
- }
- }
- } else if (worker->state == GST_STATE_PLAYING) {
- g_debug("buffering concluded, signalling "
- "state change");
- /* In this case we got a PLAY command while
- buffering, likely because it was issued
- before we got the first buffering signal.
- The UI should not do this, but if it does,
- we have to signal that we have executed
- the state change, since in
- _handle_state_changed we do not do anything
- if we are buffering */
-
- /* Set the pipeline to playing. This is an async
- handler, it could be, that the reported state
- is not the real-current state */
- if (gst_element_set_state(
- worker->pipeline,
- GST_STATE_PLAYING) ==
- GST_STATE_CHANGE_ASYNC)
- {
- /* XXX this blocks at most 2 seconds. */
- gst_element_get_state(
- worker->pipeline, NULL, NULL,
- 2 * GST_SECOND);
- }
- if (worker->report_statechanges &&
- worker->notify_play_handler) {
- worker->notify_play_handler(
- worker,
- worker->owner);
- }
- _add_duration_seek_query_timeout(worker);
- }
- }
- }
-
- /* Send buffer percentage */
- if (worker->notify_buffer_status_handler)
- worker->notify_buffer_status_handler(worker, worker->owner,
- percent);
-}
-
-static void _handle_element_msg(MafwGstRendererWorker *worker, GstMessage *msg)
-{
- /* Only HelixBin sends "resolution" messages. */
- if (gst_structure_has_name(msg->structure, "resolution") &&
- _handle_video_info(worker, msg->structure))
- {
- worker->media.has_visual_content = TRUE;
- }
-}
-
-static void _reset_pl_info(MafwGstRendererWorker *worker)
-{
- if (worker->pl.items) {
- g_slist_foreach(worker->pl.items, (GFunc) g_free, NULL);
- g_slist_free(worker->pl.items);
- worker->pl.items = NULL;
- }
-
- worker->pl.current = 0;
- worker->pl.notify_play_pending = TRUE;
-}
-
-static GError * _get_specific_missing_plugin_error(GstMessage *msg)
-{
- const GstStructure *gst_struct;
- const gchar *type;
-
- GError *error;
- gchar *desc;
-
- desc = gst_missing_plugin_message_get_description(msg);
-
- gst_struct = gst_message_get_structure(msg);
- type = gst_structure_get_string(gst_struct, "type");
-
- if ((type) && ((strcmp(type, MAFW_GST_MISSING_TYPE_DECODER) == 0) ||
- (strcmp(type, MAFW_GST_MISSING_TYPE_ENCODER) == 0))) {
-
- /* Missing codec error. */
- const GValue *val;
- const GstCaps *caps;
- GstStructure *caps_struct;
- const gchar *mime;
-
- val = gst_structure_get_value(gst_struct, "detail");
- caps = gst_value_get_caps(val);
- caps_struct = gst_caps_get_structure(caps, 0);
- mime = gst_structure_get_name(caps_struct);
-
- if (g_strrstr(mime, "video")) {
- error = g_error_new_literal(
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_VIDEO_CODEC_NOT_FOUND,
- desc);
- } else if (g_strrstr(mime, "audio")) {
- error = g_error_new_literal(
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_AUDIO_CODEC_NOT_FOUND,
- desc);
- } else {
- error = g_error_new_literal(
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_CODEC_NOT_FOUND,
- desc);
- }
- } else {
- /* Unsupported type error. */
- error = g_error_new(
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_UNSUPPORTED_TYPE,
- "missing plugin: %s", desc);
- }
-
- g_free(desc);
-
- return error;
-}
-
-/*
- * Asynchronous message handler. It gets removed from if it returns FALSE.
- */
-static gboolean _async_bus_handler(GstBus *bus, GstMessage *msg,
- MafwGstRendererWorker *worker)
-{
- /* No need to handle message if error has already occured. */
- if (worker->is_error)
- return TRUE;
-
- /* Handle missing-plugin (element) messages separately, relaying more
- * details. */
- if (gst_is_missing_plugin_message(msg)) {
- GError *err = _get_specific_missing_plugin_error(msg);
- /* FIXME?: for some reason, calling the error handler directly
- * (_send_error) causes problems. On the other hand, turning
- * the error into a new GstMessage and letting the next
- * iteration handle it seems to work. */
- _post_error(worker, err);
- return TRUE;
- }
-
- switch (GST_MESSAGE_TYPE(msg)) {
- case GST_MESSAGE_ERROR:
- if (!worker->is_error) {
- gchar *debug;
- GError *err;
-
- debug = NULL;
- gst_message_parse_error(msg, &err, &debug);
- g_debug("gst error: domain = %d, code = %d, "
- "message = '%s', debug = '%s'",
- err->domain, err->code, err->message, debug);
- if (debug)
- g_free(debug);
-
- /* If we are in playlist/radio mode, we silently
- ignore the error and continue with the next
- item until we end the playlist. If no
- playable elements we raise the error and
- after finishing we go to normal mode */
-
- if (worker->mode == WORKER_MODE_PLAYLIST ||
- worker->mode == WORKER_MODE_REDUNDANT) {
- if (worker->pl.current <
- (g_slist_length(worker->pl.items) - 1)) {
- /* If the error is "no space left"
- notify, otherwise try to play the
- next item */
- if (err->code ==
- GST_RESOURCE_ERROR_NO_SPACE_LEFT) {
- _send_error(worker, err);
-
- } else {
- _play_pl_next(worker);
- }
- } else {
- /* Playlist EOS. We cannot try another
- * URI, so we have to go back to normal
- * mode and signal the error (done
- * below) */
- worker->mode = WORKER_MODE_SINGLE_PLAY;
- _reset_pl_info(worker);
- }
- }
-
- if (worker->mode == WORKER_MODE_SINGLE_PLAY) {
- if (err->domain == GST_STREAM_ERROR &&
- err->code == GST_STREAM_ERROR_WRONG_TYPE)
- {/* Maybe it is a playlist? */
- GSList *plitems = _parse_playlist(worker->media.location);
-
- if (plitems)
- {/* Yes, it is a plitem */
- g_error_free(err);
- mafw_gst_renderer_worker_play(worker, NULL, plitems);
- break;
- }
-
-
- }
- _send_error(worker, err);
- }
- }
- break;
- case GST_MESSAGE_EOS:
- if (!worker->is_error) {
- worker->eos = TRUE;
-
- if (worker->mode == WORKER_MODE_PLAYLIST) {
- if (worker->pl.current <
- (g_slist_length(worker->pl.items) - 1)) {
- /* If the playlist EOS is not reached
- continue playing */
- _play_pl_next(worker);
- } else {
- /* Playlist EOS, go back to normal
- mode */
- worker->mode = WORKER_MODE_SINGLE_PLAY;
- _reset_pl_info(worker);
- }
- }
-
- if (worker->mode == WORKER_MODE_SINGLE_PLAY ||
- worker->mode == WORKER_MODE_REDUNDANT) {
- if (worker->notify_eos_handler)
- worker->notify_eos_handler(
- worker,
- worker->owner);
-
- /* We can remove the message handlers now, we
- are not interested in bus messages
- anymore. */
- if (worker->bus) {
- gst_bus_set_sync_handler(worker->bus,
- NULL,
- NULL);
- }
- if (worker->async_bus_id) {
- g_source_remove(worker->async_bus_id);
- worker->async_bus_id = 0;
- }
-
- if (worker->mode == WORKER_MODE_REDUNDANT) {
- /* Go to normal mode */
- worker->mode = WORKER_MODE_SINGLE_PLAY;
- _reset_pl_info(worker);
- }
- }
- }
- break;
- case GST_MESSAGE_TAG:
- _handle_tag(worker, msg);
- break;
- case GST_MESSAGE_BUFFERING:
- _handle_buffering(worker, msg);
- break;
- case GST_MESSAGE_DURATION:
- _handle_duration(worker, msg);
- break;
- case GST_MESSAGE_ELEMENT:
- _handle_element_msg(worker, msg);
- break;
- case GST_MESSAGE_STATE_CHANGED:
- if ((GstElement *)GST_MESSAGE_SRC(msg) == worker->pipeline)
- _handle_state_changed(msg, worker);
- break;
- case GST_MESSAGE_APPLICATION:
- if (gst_structure_has_name(gst_message_get_structure(msg),
- "ckey"))
- {
- GValue v = {0};
- g_value_init(&v, G_TYPE_INT);
- g_value_set_int(&v, worker->colorkey);
- mafw_extension_emit_property_changed(
- MAFW_EXTENSION(worker->owner),
- MAFW_PROPERTY_RENDERER_COLORKEY,
- &v);
- }
- default: break;
- }
- return TRUE;
-}
-
-/* NOTE this function will possibly be called from a different thread than the
- * glib main thread. */
-static void _stream_info_cb(GstObject *pipeline, GParamSpec *unused,
- MafwGstRendererWorker *worker)
-{
- g_debug("stream-info changed");
- _parse_stream_info(worker);
-}
-
-static void _volume_cb(MafwGstRendererWorkerVolume *wvolume, gdouble volume,
- gpointer data)
-{
- MafwGstRendererWorker *worker = data;
- GValue value = {0, };
-
- _reset_volume_and_mute_to_pipeline(worker);
-
- g_value_init(&value, G_TYPE_UINT);
- g_value_set_uint(&value, (guint) (volume * 100.0));
- mafw_extension_emit_property_changed(MAFW_EXTENSION(worker->owner),
- MAFW_PROPERTY_RENDERER_VOLUME,
- &value);
-}
-
-#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
-
-static void _mute_cb(MafwGstRendererWorkerVolume *wvolume, gboolean mute,
- gpointer data)
-{
- MafwGstRendererWorker *worker = data;
- GValue value = {0, };
-
- _reset_volume_and_mute_to_pipeline(worker);
-
- g_value_init(&value, G_TYPE_BOOLEAN);
- g_value_set_boolean(&value, mute);
- mafw_extension_emit_property_changed(MAFW_EXTENSION(worker->owner),
- MAFW_PROPERTY_RENDERER_MUTE,
- &value);
-}
-
-#endif
-
-/* TODO: I think it's not enought to act on error, we need to handle
- * DestroyNotify on the given window ourselves, because for example helixbin
- * does it and silently stops the decoder thread. But it doesn't notify
- * us... */
-static int xerror(Display *dpy, XErrorEvent *xev)
-{
- MafwGstRendererWorker *worker;
-
- if (Global_worker == NULL) {
- return -1;
- } else {
- worker = Global_worker;
- }
-
- /* Swallow BadWindow and stop pipeline when the error is about the
- * currently set xid. */
- if (worker->xid &&
- xev->resourceid == worker->xid &&
- xev->error_code == BadWindow)
- {
- g_warning("BadWindow received for current xid (%x).",
- (gint)xev->resourceid);
- worker->xid = 0;
- /* We must post a message to the bus, because this function is
- * invoked from a different thread (xvimagerenderer's queue). */
- _post_error(worker, g_error_new_literal(
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_PLAYBACK,
- "Video window gone"));
- }
- return 0;
-}
-
-/*
- * Resets the media information.
- */
-static void _reset_media_info(MafwGstRendererWorker *worker)
-{
- if (worker->media.location) {
- g_free(worker->media.location);
- worker->media.location = NULL;
- }
- worker->media.length_nanos = -1;
- worker->media.has_visual_content = FALSE;
- worker->media.seekable = SEEKABILITY_UNKNOWN;
- worker->media.video_width = 0;
- worker->media.video_height = 0;
- worker->media.fps = 0.0;
-}
-
-static void _set_volume_and_mute(MafwGstRendererWorker *worker, gdouble vol,
- gboolean mute)
-{
- g_return_if_fail(worker->wvolume != NULL);
-
- mafw_gst_renderer_worker_volume_set(worker->wvolume, vol, mute);
-}
-
-static void _set_volume(MafwGstRendererWorker *worker, gdouble new_vol)
-{
- g_return_if_fail(worker->wvolume != NULL);
-
- _set_volume_and_mute(
- worker, new_vol,
- mafw_gst_renderer_worker_volume_is_muted(worker->wvolume));
-}
-
-static void _set_mute(MafwGstRendererWorker *worker, gboolean mute)
-{
- g_return_if_fail(worker->wvolume != NULL);
-
- _set_volume_and_mute(
- worker, mafw_gst_renderer_worker_volume_get(worker->wvolume),
- mute);
-}
-
-/*
- * Start to play the media
- */
-static void _start_play(MafwGstRendererWorker *worker)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer*) worker->owner;
- GstStateChangeReturn state_change_info;
- char *autoload_sub = NULL;
-
- g_assert(worker->pipeline);
- g_object_set(G_OBJECT(worker->pipeline),
- "uri", worker->media.location, NULL);
-
- if (worker->subtitles.enabled) {
- autoload_sub = uri_get_subtitle_uri(worker->media.location);
- if (autoload_sub) {
- g_debug("SUBURI: %s", autoload_sub);
- g_object_set(G_OBJECT(worker->pipeline),
- "suburi", autoload_sub,
- "subtitle-font-desc", worker->subtitles.font,
- "subtitle-encoding", worker->subtitles.encoding,
- NULL);
-
- gst_element_set_state(worker->pipeline, GST_STATE_READY);
- g_free(autoload_sub);
- }
- } else {
- g_object_set(G_OBJECT(worker->pipeline), "suburi", NULL, NULL);
- }
-
- g_debug("URI: %s", worker->media.location);
- g_debug("setting pipeline to PAUSED");
-
- worker->report_statechanges = TRUE;
- state_change_info = gst_element_set_state(worker->pipeline,
- GST_STATE_PAUSED);
- if (state_change_info == GST_STATE_CHANGE_NO_PREROLL) {
- /* FIXME: for live sources we may have to handle
- buffering and prerolling differently */
- g_debug ("Source is live!");
- worker->is_live = TRUE;
- }
- worker->prerolling = TRUE;
-
- worker->is_stream = uri_is_stream(worker->media.location);
-
- if (renderer->update_playcount_id > 0) {
- g_source_remove(renderer->update_playcount_id);
- renderer->update_playcount_id = 0;
- }
-
-}
-
-/*
- * Constructs gst pipeline
- *
- * FIXME: Could the same pipeline be used for playing all media instead of
- * constantly deleting and reconstructing it again?
- */
-static void _construct_pipeline(MafwGstRendererWorker *worker)
-{
- g_debug("constructing pipeline");
- g_assert(worker != NULL);
-
- /* Return if we have already one */
- if (worker->pipeline)
- return;
-
- _free_taglist(worker);
-
- g_debug("Creating a new instance of playbin2");
- worker->pipeline = gst_element_factory_make("playbin2",
- "playbin");
- if (worker->pipeline == NULL)
- {
- /* Let's try with playbin */
- g_warning ("playbin2 failed, falling back to playbin");
- worker->pipeline = gst_element_factory_make("playbin",
- "playbin");
-
- if (worker->pipeline) {
- /* Use nwqueue only for non-rtsp and non-mms(h)
- streams. */
- gboolean use_nw;
- use_nw = worker->media.location &&
- !g_str_has_prefix(worker->media.location,
- "rtsp://") &&
- !g_str_has_prefix(worker->media.location,
- "mms://") &&
- !g_str_has_prefix(worker->media.location,
- "mmsh://");
-
- g_debug("playbin using network queue: %d", use_nw);
-
- /* These need a modified version of playbin. */
- g_object_set(G_OBJECT(worker->pipeline),
- "nw-queue", use_nw,
- "no-video-transform", TRUE,
- NULL);
- }
- }
-
- if (!worker->pipeline) {
- g_critical("failed to create playback pipeline");
- g_signal_emit_by_name(MAFW_EXTENSION (worker->owner),
- "error",
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_UNABLE_TO_PERFORM,
- "Could not create pipeline");
- g_assert_not_reached();
- }
-
-
- worker->bus = gst_pipeline_get_bus(GST_PIPELINE(worker->pipeline));
- gst_bus_set_sync_handler(worker->bus,
- (GstBusSyncHandler)_sync_bus_handler, worker);
- worker->async_bus_id = gst_bus_add_watch_full(worker->bus,G_PRIORITY_HIGH,
- (GstBusFunc)_async_bus_handler,
- worker, NULL);
-
- /* Listen for changes in stream-info object to find out whether the
- * media contains video and throw error if application has not provided
- * video window. */
- g_signal_connect(worker->pipeline, "notify::stream-info",
- G_CALLBACK(_stream_info_cb), worker);
-
-#ifndef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME
-
-
- /* Set audio and video sinks ourselves. We create and configure
- them only once. */
- if (!worker->asink) {
- worker->asink = gst_element_factory_make("pulsesink", NULL);
- if (!worker->asink) {
- g_critical("Failed to create pipeline audio sink");
- g_signal_emit_by_name(MAFW_EXTENSION (worker->owner),
- "error",
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_UNABLE_TO_PERFORM,
- "Could not create audio sink");
- g_assert_not_reached();
- }
- gst_object_ref(worker->asink);
- g_object_set(worker->asink,
- "buffer-time", (gint64) MAFW_GST_BUFFER_TIME,
- "latency-time", (gint64) MAFW_GST_LATENCY_TIME,
- NULL);
- }
- g_object_set(worker->pipeline, "audio-sink", worker->asink, NULL);
-#endif
-
- if (!worker->vsink) {
- worker->vsink = gst_element_factory_make("xvimagesink", NULL);
- if (!worker->vsink) {
- g_critical("Failed to create pipeline video sink");
- g_signal_emit_by_name(MAFW_EXTENSION (worker->owner),
- "error",
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_UNABLE_TO_PERFORM,
- "Could not create video sink");
- g_assert_not_reached();
- }
- gst_object_ref(worker->vsink);
- g_object_set(G_OBJECT(worker->vsink),
- "handle-events", TRUE,
- "force-aspect-ratio", TRUE,
- NULL);
- }
- g_object_set(worker->pipeline,
- "video-sink", worker->vsink,
- "flags", 103,
- NULL);
-
- if (!worker->tsink) {
- worker->tsink = gst_element_factory_make("textoverlay", NULL);
- if (!worker->tsink) {
- g_critical("Failed to create pipeline text sink");
- g_signal_emit_by_name(MAFW_EXTENSION (worker->owner),
- "error",
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_UNABLE_TO_PERFORM,
- "Could not create text sink");
- g_assert_not_reached();
- }
- gst_object_ref(worker->tsink);
- }
- g_object_set(worker->pipeline, "text-sink", worker->tsink, NULL);
-}
-
-/*
- * @seek_type: GstSeekType
- * @position: Time in seconds where to seek
- */
-static void _do_seek(MafwGstRendererWorker *worker, GstSeekType seek_type,
- gint position, GError **error)
-{
- gboolean ret;
- gint64 spos;
-
- g_assert(worker != NULL);
-
- if (worker->eos || !worker->media.seekable)
- goto err;
-
- /* According to the docs, relative seeking is not so easy:
- GST_SEEK_TYPE_CUR - change relative to currently configured segment.
- This can't be used to seek relative to the current playback position -
- do a position query, calculate the desired position and then do an
- absolute position seek instead if that's what you want to do. */
- if (seek_type == GST_SEEK_TYPE_CUR)
- {
- gint curpos = mafw_gst_renderer_worker_get_position(worker);
- position = curpos + position;
- seek_type = GST_SEEK_TYPE_SET;
- }
-
- if (position < 0) {
- position = 0;
- }
-
- worker->seek_position = position;
- worker->report_statechanges = FALSE;
- spos = (gint64)position * GST_SECOND;
- g_debug("seek: type = %d, offset = %lld", seek_type, spos);
-
- /* If the pipeline has been set to READY by us, then wake it up by
- setting it to PAUSED (when we get the READY->PAUSED transition
- we will execute the seek). This way when we seek we disable the
- READY state (logical, since the player is not idle anymore)
- allowing the sink to render the destination frame in case of
- video playback */
- if (worker->in_ready && worker->state == GST_STATE_READY) {
- gst_element_set_state(worker->pipeline, GST_STATE_PAUSED);
- } else {
- ret = gst_element_seek(worker->pipeline, 1.0, GST_FORMAT_TIME,
- GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_KEY_UNIT,
- seek_type, spos,
- GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
- if (!ret) {
- /* Seeking is async, so seek_position should not be
- invalidated here */
- goto err;
- }
- }
- return;
-
-err: g_set_error(error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_CANNOT_SET_POSITION,
- "Seeking to %d failed", position);
-}
-
-/* @vol should be between [0 .. 100], higher values (up to 1000) are allowed,
- * but probably cause distortion. */
-void mafw_gst_renderer_worker_set_volume(
- MafwGstRendererWorker *worker, guint volume)
-{
- _set_volume(worker, CLAMP((gdouble)volume / 100.0, 0.0, 1.0));
-}
-
-guint mafw_gst_renderer_worker_get_volume(
- MafwGstRendererWorker *worker)
-{
- return (guint)
- (mafw_gst_renderer_worker_volume_get(worker->wvolume) * 100);
-}
-
-void mafw_gst_renderer_worker_set_mute(MafwGstRendererWorker *worker,
- gboolean mute)
-{
- _set_mute(worker, mute);
-}
-
-gboolean mafw_gst_renderer_worker_get_mute(MafwGstRendererWorker *worker)
-{
- return mafw_gst_renderer_worker_volume_is_muted(worker->wvolume);
-}
-
-#ifdef HAVE_GDKPIXBUF
-void mafw_gst_renderer_worker_set_current_frame_on_pause(MafwGstRendererWorker *worker,
- gboolean current_frame_on_pause)
-{
- worker->current_frame_on_pause = current_frame_on_pause;
-}
-
-gboolean mafw_gst_renderer_worker_get_current_frame_on_pause(MafwGstRendererWorker *worker)
-{
- return worker->current_frame_on_pause;
-}
-#endif
-
-void mafw_gst_renderer_worker_set_position(MafwGstRendererWorker *worker,
- GstSeekType seek_type,
- gint position, GError **error)
-{
- /* If player is paused and we have a timeout for going to ready
- * restart it. This is logical, since the user is seeking and
- * thus, the player is not idle anymore. Also this prevents that
- * when seeking streams we enter buffering and in the middle of
- * the buffering process we set the pipeline to ready (which stops
- * the buffering before it reaches 100%, making the client think
- * buffering is still going on).
- */
- if (worker->ready_timeout) {
- _remove_ready_timeout(worker);
- _add_ready_timeout(worker);
- }
-
- _do_seek(worker, seek_type, position, error);
- if (worker->notify_seek_handler)
- worker->notify_seek_handler(worker, worker->owner);
-}
-
-/*
- * Gets current position, rounded down into precision of one second. If a seek
- * is pending, returns the position we are going to seek. Returns -1 on
- * failure.
- */
-gint mafw_gst_renderer_worker_get_position(MafwGstRendererWorker *worker)
-{
- GstFormat format;
- gint64 time = 0;
- g_assert(worker != NULL);
-
- /* If seek is ongoing, return the position where we are seeking. */
- if (worker->seek_position != -1)
- {
- return worker->seek_position;
- }
- /* Otherwise query position from pipeline. */
- format = GST_FORMAT_TIME;
- if (worker->pipeline &&
- gst_element_query_position(worker->pipeline, &format, &time))
- {
- return (gint)(NSECONDS_TO_SECONDS(time));
- }
- return -1;
-}
-
-GHashTable *mafw_gst_renderer_worker_get_current_metadata(
- MafwGstRendererWorker *worker)
-{
- return worker->current_metadata;
-}
-
-void mafw_gst_renderer_worker_set_xid(MafwGstRendererWorker *worker, XID xid)
-{
- /* Check for errors on the target window */
- XSetErrorHandler(xerror);
-
- /* Store the target window id */
- g_debug("Setting xid: %x", (guint)xid);
- worker->xid = xid;
-
- /* Check if we should use it right away */
- mafw_gst_renderer_worker_apply_xid(worker);
-}
-
-XID mafw_gst_renderer_worker_get_xid(MafwGstRendererWorker *worker)
-{
- return worker->xid;
-}
-
-gboolean mafw_gst_renderer_worker_get_autopaint(
- MafwGstRendererWorker *worker)
-{
- return worker->autopaint;
-}
-void mafw_gst_renderer_worker_set_autopaint(
- MafwGstRendererWorker *worker, gboolean autopaint)
-{
- worker->autopaint = autopaint;
- if (worker->vsink)
- g_object_set(worker->vsink, "autopaint-colorkey",
- worker->autopaint, NULL);
-}
-
-gint mafw_gst_renderer_worker_get_colorkey(
- MafwGstRendererWorker *worker)
-{
- return worker->colorkey;
-}
-
-void mafw_gst_renderer_worker_set_colorkey(
- MafwGstRendererWorker *worker, gint colorkey)
-{
- worker->colorkey = colorkey;
- if (worker->vsink)
- g_object_set(worker->vsink, "colorkey",
- worker->colorkey, NULL);
-}
-
-gboolean mafw_gst_renderer_worker_get_seekable(MafwGstRendererWorker *worker)
-{
- return worker->media.seekable;
-}
-
-static void _play_pl_next(MafwGstRendererWorker *worker) {
- gchar *next;
-
- g_assert(worker != NULL);
- g_return_if_fail(worker->pl.items != NULL);
-
- next = (gchar *) g_slist_nth_data(worker->pl.items,
- ++worker->pl.current);
- mafw_gst_renderer_worker_stop(worker);
- _reset_media_info(worker);
-
- worker->media.location = g_strdup(next);
- _construct_pipeline(worker);
- _start_play(worker);
-}
-
-static void _do_play(MafwGstRendererWorker *worker)
-{
- g_assert(worker != NULL);
-
- if (worker->pipeline == NULL) {
- g_debug("play without a pipeline!");
- return;
- }
- worker->report_statechanges = TRUE;
-
- /* If we have to stay paused, we do and add the ready
- * timeout. Otherwise, we move the pipeline */
- if (!worker->stay_paused) {
- /* If pipeline is READY, we move it to PAUSED,
- * otherwise, to PLAYING */
- if (worker->state == GST_STATE_READY) {
- gst_element_set_state(worker->pipeline,
- GST_STATE_PAUSED);
- g_debug("setting pipeline to PAUSED");
- } else {
- _reset_volume_and_mute_to_pipeline(worker);
- gst_element_set_state(worker->pipeline,
- GST_STATE_PLAYING);
- g_debug("setting pipeline to PLAYING");
- }
- }
- else {
- g_debug("staying in PAUSED state");
- _add_ready_timeout(worker);
- }
-}
-
-void mafw_gst_renderer_worker_play(MafwGstRendererWorker *worker,
- const gchar *uri, GSList *plitems)
-{
- g_assert(uri || plitems);
-
- mafw_gst_renderer_worker_stop(worker);
- _reset_media_info(worker);
- _reset_pl_info(worker);
- /* Check if the item to play is a single item or a playlist. */
- if (plitems || uri_is_playlist(uri)){
- gchar *item;
- /* In case of a playlist we parse it and start playing the first
- item of the playlist. */
- if (plitems)
- {
- worker->pl.items = plitems;
- }
- else
- {
- worker->pl.items = _parse_playlist(uri);
- }
- if (!worker->pl.items)
- {
- _send_error(worker,
- g_error_new(MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_PLAYLIST_PARSING,
- "Playlist parsing failed: %s",
- uri));
- return;
- }
-
- /* Set the playback mode */
- worker->mode = WORKER_MODE_PLAYLIST;
- worker->pl.notify_play_pending = TRUE;
-
- /* Set the item to be played */
- worker->pl.current = 0;
- item = (gchar *) g_slist_nth_data(worker->pl.items, 0);
- worker->media.location = g_strdup(item);
- } else {
- /* Single item. Set the playback mode according to that */
- worker->mode = WORKER_MODE_SINGLE_PLAY;
-
- /* Set the item to be played */
- worker->media.location = g_strdup(uri);
- }
- _construct_pipeline(worker);
- _start_play(worker);
-}
-
-void mafw_gst_renderer_worker_play_alternatives(MafwGstRendererWorker *worker,
- gchar **uris)
-{
- gint i;
- gchar *item;
-
- g_assert(uris && uris[0]);
-
- mafw_gst_renderer_worker_stop(worker);
- _reset_media_info(worker);
- _reset_pl_info(worker);
-
- /* Add the uris to playlist */
- i = 0;
- while (uris[i]) {
- worker->pl.items =
- g_slist_append(worker->pl.items, g_strdup(uris[i]));
- i++;
- }
-
- /* Set the playback mode */
- worker->mode = WORKER_MODE_REDUNDANT;
- worker->pl.notify_play_pending = TRUE;
-
- /* Set the item to be played */
- worker->pl.current = 0;
- item = (gchar *) g_slist_nth_data(worker->pl.items, 0);
- worker->media.location = g_strdup(item);
-
- /* Start playing */
- _construct_pipeline(worker);
- _start_play(worker);
-}
-
-/*
- * Currently, stop destroys the Gst pipeline and resets the worker into
- * default startup configuration.
- */
-void mafw_gst_renderer_worker_stop(MafwGstRendererWorker *worker)
-{
- g_debug("worker stop");
- g_assert(worker != NULL);
-
- /* If location is NULL, this is a pre-created pipeline */
- if (worker->async_bus_id && worker->pipeline && !worker->media.location)
- return;
-
- if (worker->pipeline) {
- g_debug("destroying pipeline");
- if (worker->async_bus_id) {
- g_source_remove(worker->async_bus_id);
- worker->async_bus_id = 0;
- }
- gst_bus_set_sync_handler(worker->bus, NULL, NULL);
- gst_element_set_state(worker->pipeline, GST_STATE_NULL);
- if (worker->bus) {
- gst_object_unref(GST_OBJECT_CAST(worker->bus));
- worker->bus = NULL;
- }
- gst_object_unref(GST_OBJECT(worker->pipeline));
- worker->pipeline = NULL;
- }
-
- /* Reset worker */
- worker->report_statechanges = TRUE;
- worker->state = GST_STATE_NULL;
- worker->prerolling = FALSE;
- worker->is_live = FALSE;
- worker->buffering = FALSE;
- worker->is_stream = FALSE;
- worker->is_error = FALSE;
- worker->eos = FALSE;
- worker->seek_position = -1;
- _remove_ready_timeout(worker);
- _free_taglist(worker);
- if (worker->current_metadata) {
- g_hash_table_destroy(worker->current_metadata);
- worker->current_metadata = NULL;
- }
-
- if (worker->duration_seek_timeout != 0) {
- g_source_remove(worker->duration_seek_timeout);
- worker->duration_seek_timeout = 0;
- }
-
- /* Reset media iformation */
- _reset_media_info(worker);
-
- /* We are not playing, so we can let the screen blank */
- blanking_allow();
- keypadlocking_allow();
-
- /* And now get a fresh pipeline ready */
- _construct_pipeline(worker);
-}
-
-void mafw_gst_renderer_worker_pause(MafwGstRendererWorker *worker)
-{
- g_assert(worker != NULL);
-
- if (worker->buffering && worker->state == GST_STATE_PAUSED &&
- !worker->prerolling) {
- /* If we are buffering and get a pause, we have to
- * signal state change and stay_paused */
- g_debug("Pausing while buffering, signalling state change");
- worker->stay_paused = TRUE;
- if (worker->notify_pause_handler) {
- worker->notify_pause_handler(
- worker,
- worker->owner);
- }
- } else {
- worker->report_statechanges = TRUE;
-
- if (gst_element_set_state(worker->pipeline, GST_STATE_PAUSED) ==
- GST_STATE_CHANGE_ASYNC)
- {
- /* XXX this blocks at most 2 seconds. */
- gst_element_get_state(worker->pipeline, NULL, NULL,
- 2 * GST_SECOND);
- }
- blanking_allow();
- keypadlocking_allow();
- }
-}
-
-void mafw_gst_renderer_worker_resume(MafwGstRendererWorker *worker)
-{
- if (worker->mode == WORKER_MODE_PLAYLIST ||
- worker->mode == WORKER_MODE_REDUNDANT) {
- /* We must notify play if the "playlist" playback
- is resumed */
- worker->pl.notify_play_pending = TRUE;
- }
- if (worker->buffering && worker->state == GST_STATE_PAUSED &&
- !worker->prerolling) {
- /* If we are buffering we cannot resume, but we know
- * that the pipeline will be moved to PLAYING as
- * stay_paused is FALSE, so we just activate the state
- * change report, this way as soon as buffering is finished
- * the pipeline will be set to PLAYING and the state
- * change will be reported */
- worker->report_statechanges = TRUE;
- g_debug("Resumed while buffering, activating pipeline state "
- "changes");
- /* Notice though that we can receive the Resume before
- we get any buffering information. In that case
- we go with the "else" branch and set the pipeline to
- to PLAYING. However, it is possible that in this case
- we get the fist buffering signal before the
- PAUSED -> PLAYING state change. In that case, since we
- ignore state changes while buffering we never signal
- the state change to PLAYING. We can only fix this by
- checking, when we receive a PAUSED -> PLAYING transition
- if we are buffering, and in that case signal the state
- change (if we get that transition while buffering
- is on, it can only mean that the client resumed playback
- while buffering, and we must notify the state change) */
- } else {
- _do_play(worker);
- }
-}
-
-static void _volume_init_cb(MafwGstRendererWorkerVolume *wvolume,
- gpointer data)
-{
- MafwGstRendererWorker *worker = data;
- gdouble volume;
- gboolean mute;
-
- worker->wvolume = wvolume;
-
- g_debug("volume manager initialized");
-
- volume = mafw_gst_renderer_worker_volume_get(wvolume);
- mute = mafw_gst_renderer_worker_volume_is_muted(wvolume);
- _volume_cb(wvolume, volume, worker);
-#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
- _mute_cb(wvolume, mute, worker);
-#endif
-}
-
-MafwGstRendererWorker *mafw_gst_renderer_worker_new(gpointer owner)
-{
- MafwGstRendererWorker *worker;
- GMainContext *main_context;
-
- worker = g_new0(MafwGstRendererWorker, 1);
- worker->mode = WORKER_MODE_SINGLE_PLAY;
- worker->pl.items = NULL;
- worker->pl.current = 0;
- worker->pl.notify_play_pending = TRUE;
- worker->owner = owner;
- worker->report_statechanges = TRUE;
- worker->state = GST_STATE_NULL;
- worker->seek_position = -1;
- worker->ready_timeout = 0;
- worker->in_ready = FALSE;
- worker->xid = 0;
- worker->autopaint = TRUE;
- worker->colorkey = -1;
- worker->vsink = NULL;
- worker->asink = NULL;
- worker->tsink = NULL;
- worker->tag_list = NULL;
- worker->current_metadata = NULL;
- worker->subtitles.enabled = FALSE;
- worker->subtitles.font = NULL;
- worker->subtitles.encoding = NULL;
-
-#ifdef HAVE_GDKPIXBUF
- worker->current_frame_on_pause = FALSE;
- _init_tmp_files_pool(worker);
-#endif
- worker->notify_seek_handler = NULL;
- worker->notify_pause_handler = NULL;
- worker->notify_play_handler = NULL;
- worker->notify_buffer_status_handler = NULL;
- worker->notify_eos_handler = NULL;
- worker->notify_error_handler = NULL;
- Global_worker = worker;
- main_context = g_main_context_default();
- worker->wvolume = NULL;
- mafw_gst_renderer_worker_volume_init(main_context,
- _volume_init_cb, worker,
- _volume_cb, worker,
-#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
- _mute_cb,
-#else
- NULL,
-#endif
- worker);
- blanking_init();
- _construct_pipeline(worker);
-
- return worker;
-}
-
-void mafw_gst_renderer_worker_exit(MafwGstRendererWorker *worker)
-{
- blanking_deinit();
-#ifdef HAVE_GDKPIXBUF
- _destroy_tmp_files_pool(worker);
-#endif
- mafw_gst_renderer_worker_volume_destroy(worker->wvolume);
- mafw_gst_renderer_worker_stop(worker);
-}
-/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef MAFW_GST_RENDERER_WORKER_H
-#define MAFW_GST_RENDERER_WORKER_H
-
-#include <X11/Xdefs.h>
-#include <glib-object.h>
-#include <gst/gst.h>
-#include "mafw-gst-renderer-worker-volume.h"
-
-#define MAFW_GST_RENDERER_MAX_TMP_FILES 5
-
-typedef struct _MafwGstRendererWorker MafwGstRendererWorker;
-
-typedef void (*MafwGstRendererWorkerNotifySeekCb)(MafwGstRendererWorker *worker, gpointer owner);
-typedef void (*MafwGstRendererWorkerNotifyPauseCb)(MafwGstRendererWorker *worker, gpointer owner);
-typedef void (*MafwGstRendererWorkerNotifyPlayCb)(MafwGstRendererWorker *worker, gpointer owner);
-typedef void (*MafwGstRendererWorkerNotifyBufferStatusCb)(MafwGstRendererWorker *worker, gpointer owner, gdouble percent);
-typedef void (*MafwGstRendererWorkerNotifyEOSCb)(MafwGstRendererWorker *worker, gpointer owner);
-typedef void (*MafwGstRendererWorkerNotifyErrorCb)(MafwGstRendererWorker *worker,
- gpointer owner,
- const GError *error);
-
-typedef enum {
- WORKER_MODE_SINGLE_PLAY,
- WORKER_MODE_PLAYLIST,
- WORKER_MODE_REDUNDANT,
-} PlaybackMode;
-
-typedef enum {
- SEEKABILITY_UNKNOWN = -1,
- SEEKABILITY_NO_SEEKABLE,
- SEEKABILITY_SEEKABLE,
-} SeekabilityType;
-
-/*
- * media: Information about currently selected media.
- * location: Current media location
- * length_nanos: Length of the media, in nanoseconds
- * has_visual_content: the clip contains some visual content (video)
- * video_width: If media contains video, this tells the video width
- * video_height: If media contains video, this tells the video height
- * seekable: Tells whether the media can be seeked
- * par_n: Video pixel aspect ratio numerator
- * par_d: Video pixel aspect ratio denominator
- * subtitles: Configuration of subtitles.
- * enabled: Are subtitles enabled
- * font: Subtitles font description
- * encoding: Subtitles encoding
- * owner: Owner of the worker; usually a MafwGstRenderer (FIXME USUALLY?)
- * pipeline: Playback pipeline
- * bus: Message bus
- * state: Current playback pipeline state
- * is_stream: Is currently playing media a stream
- * muted: Is the audio muted
- * eos: Has playback reached EOS already
- * is_error: Has there been an error situation
- * buffering: Indicates the buffering state
- * prerolling: Indicates the prerolling state (NULL -> PAUSED)
- * report_statechanges: Report state change bus messages
- * current_volume: Current audio volume [0.0 .. 1.0], see playbin:volume
- * async_bus_id: ID handle for GstBus
- * buffer_probe_id: ID of the video renderer buffer probe
- * seek_position: Indicates the pos where to seek, in seconds
- * vsink: Video sink element of the pipeline
- * asink: Audio sink element of the pipeline
- * tsink: Text sink element of the pipeline
- * xid: XID for video playback
- * current_frame_on_pause: whether to emit current frame when pausing
- */
-struct _MafwGstRendererWorker {
- struct {
- gchar *location;
- gint64 length_nanos;
- gboolean has_visual_content;
- gint video_width;
- gint video_height;
- gdouble fps;
- SeekabilityType seekable;
- gint par_n;
- gint par_d;
- } media;
- struct {
- gboolean enabled;
- gchar *font;
- gchar *encoding;
- } subtitles;
- PlaybackMode mode;
- struct {
- GSList *items;
- gint current;
- gboolean notify_play_pending;
- } pl;
- gpointer owner;
- GstElement *pipeline;
- GstBus *bus;
- /* GStreamer state we are considering right now */
- GstState state;
- MafwGstRendererWorkerVolume *wvolume;
- gboolean is_stream;
- gboolean muted;
- /* we are handing eos or we did */
- gboolean eos;
- /* if we are handling (or handled) and error */
- gboolean is_error;
- /* pipeline is buffering */
- gboolean buffering;
- /* pipeline is prerolling */
- gboolean prerolling;
- /* stream is live and doesn't need prerolling */
- gboolean is_live;
- /* if we have to stay in paused though a do_play was
- * requested. Usually used when pausing in transitioning */
- gboolean stay_paused;
- /* this variable should be FALSE while we are hiding state
- * changed to the UI. This is that GStreamer can perform
- * state_changes without us requiring it, for example, then
- * seeking, buffering and so on and we have to hide those
- * changes */
- gboolean report_statechanges;
- guint async_bus_id;
- gint seek_position;
- guint ready_timeout;
- guint duration_seek_timeout;
- /* After some time PAUSED, we set the pipeline to READY in order to
- * save resources. This field states if we are in this special
- * situation.
- * It is set to TRUE when the state change to READY is requested
- * and stays like that until we reach again PLAYING state (not PAUSED).
- * The reason for this is that when resuming streams, we have to
- * move from READY to PAUSED, then seek to the position where the
- * stream had been paused, then wait for buffering to finish, and then
- * play (and notify the state change to PLAYING), and we have to
- * differentiate this case from the one in which we have entered PAUSED
- * silently (when we ran out of buffer while playing, because in that
- * case, when we are done buffering we want to resume playback silently
- * again.
- */
- gboolean in_ready;
- GstElement *vsink;
- GstElement *asink;
- GstElement *tsink;
- XID xid;
- gboolean autopaint;
- gint colorkey;
- GPtrArray *tag_list;
- GHashTable *current_metadata;
-
-#ifdef HAVE_GDKPIXBUF
- gboolean current_frame_on_pause;
- gchar *tmp_files_pool[MAFW_GST_RENDERER_MAX_TMP_FILES];
- guint8 tmp_files_pool_index;
-#endif
-
- /* Handlers for notifications */
- MafwGstRendererWorkerNotifySeekCb notify_seek_handler;
- MafwGstRendererWorkerNotifyPauseCb notify_pause_handler;
- MafwGstRendererWorkerNotifyPlayCb notify_play_handler;
- MafwGstRendererWorkerNotifyBufferStatusCb notify_buffer_status_handler;
- MafwGstRendererWorkerNotifyEOSCb notify_eos_handler;
- MafwGstRendererWorkerNotifyErrorCb notify_error_handler;
-};
-
-G_BEGIN_DECLS
-
-MafwGstRendererWorker *mafw_gst_renderer_worker_new(gpointer owner);
-void mafw_gst_renderer_worker_exit(MafwGstRendererWorker *worker);
-
-void mafw_gst_renderer_worker_set_volume(MafwGstRendererWorker *worker,
- guint vol);
-guint mafw_gst_renderer_worker_get_volume(MafwGstRendererWorker *worker);
-void mafw_gst_renderer_worker_set_mute(MafwGstRendererWorker *worker,
- gboolean mute);
-gboolean mafw_gst_renderer_worker_get_mute(MafwGstRendererWorker *worker);
-#ifdef HAVE_GDKPIXBUF
-void mafw_gst_renderer_worker_set_current_frame_on_pause(MafwGstRendererWorker *worker,
- gboolean current_frame_on_pause);
-gboolean mafw_gst_renderer_worker_get_current_frame_on_pause(MafwGstRendererWorker *worker);
-#endif
-void mafw_gst_renderer_worker_set_position(MafwGstRendererWorker *worker,
- GstSeekType seek_type,
- gint position,
- GError **error);
-gint mafw_gst_renderer_worker_get_position(MafwGstRendererWorker *worker);
-void mafw_gst_renderer_worker_set_xid(MafwGstRendererWorker *worker, XID xid);
-XID mafw_gst_renderer_worker_get_xid(MafwGstRendererWorker *worker);
-gboolean mafw_gst_renderer_worker_get_autopaint(MafwGstRendererWorker *worker);
-void mafw_gst_renderer_worker_set_autopaint(MafwGstRendererWorker *worker, gboolean autopaint);
-gint mafw_gst_renderer_worker_get_colorkey(MafwGstRendererWorker *worker);
-void mafw_gst_renderer_worker_set_colorkey(MafwGstRendererWorker *worker, gint autopaint);
-gboolean mafw_gst_renderer_worker_get_seekable(MafwGstRendererWorker *worker);
-GHashTable *mafw_gst_renderer_worker_get_current_metadata(MafwGstRendererWorker *worker);
-void mafw_gst_renderer_worker_play(MafwGstRendererWorker *worker, const gchar *uri, GSList *plitems);
-void mafw_gst_renderer_worker_play_alternatives(MafwGstRendererWorker *worker, gchar **uris);
-void mafw_gst_renderer_worker_stop(MafwGstRendererWorker *worker);
-void mafw_gst_renderer_worker_pause(MafwGstRendererWorker *worker);
-void mafw_gst_renderer_worker_resume(MafwGstRendererWorker *worker);
-
-G_END_DECLS
-#endif
-/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <glib.h>
-#include <string.h>
-#include <stdlib.h>
-#include <dbus/dbus.h>
-#include <libgnomevfs/gnome-vfs.h>
-
-#include <libmafw/mafw.h>
-#include "mafw-gst-renderer.h"
-#include "mafw-gst-renderer-utils.h"
-#include "mafw-gst-renderer-worker.h"
-
-#include "mafw-gst-renderer-state-playing.h"
-#include "mafw-gst-renderer-state-stopped.h"
-#include "mafw-gst-renderer-state-paused.h"
-#include "mafw-gst-renderer-state-transitioning.h"
-
-#include "blanking.h"
-
-#ifdef HAVE_CONIC
-#include <conicconnectionevent.h>
-#endif
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer"
-
-#define is_current_uri_stream(self) \
- (((self)->media != NULL) && ((self)->media->uri != NULL) && \
- uri_is_stream((self)->media->uri))
-
-#define GCONF_OSSO_AF "/system/osso/af"
-#define GCONF_BATTERY_COVER_OPEN "/system/osso/af/mmc-cover-open"
-#define GCONF_MAFW_GST_SUBTITLES_RENDERER "/system/mafw/mafw-gst-subtitles-renderer"
-#define HAL_VIDEOOUT_UDI "/org/freedesktop/Hal/devices" \
- "/platform_soc_audio_logicaldev_input"
-
-/*----------------------------------------------------------------------------
- Static variable definitions
- ----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
- Plugin initialization
- ----------------------------------------------------------------------------*/
-
-static gboolean mafw_gst_renderer_initialize(MafwRegistry *registry,
- GError **error);
-static void mafw_gst_renderer_deinitialize(GError **error);
-
-/*----------------------------------------------------------------------------
- GObject initialization
- ----------------------------------------------------------------------------*/
-
-static void mafw_gst_renderer_dispose(GObject *object);
-static void mafw_gst_renderer_finalize(GObject *object);
-
-/*----------------------------------------------------------------------------
- Hal callbacks
- ----------------------------------------------------------------------------*/
-static void _property_modified(LibHalContext *ctx, const char *udi,
- const char *key, dbus_bool_t is_removed,
- dbus_bool_t is_added);
-static gboolean _tv_out_is_connected(LibHalContext *ctx, const char *udi);
-
-/*----------------------------------------------------------------------------
- GConf notifications
- ----------------------------------------------------------------------------*/
-
-static void _battery_cover_open_cb(GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- MafwGstRenderer *renderer);
-
-static void _autoload_subtitles_changed_cb(GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- MafwGstRenderer *renderer);
-
-static void _subtitle_font_changed_cb(GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- MafwGstRenderer *renderer);
-
-/*----------------------------------------------------------------------------
- Gnome VFS notifications
- ----------------------------------------------------------------------------*/
-
-static void _volume_pre_unmount_cb(GnomeVFSVolumeMonitor *monitor,
- GnomeVFSVolume *volume,
- MafwGstRenderer *renderer);
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-static void _signal_state_changed(MafwGstRenderer * self);
-static void _signal_media_changed(MafwGstRenderer * self);
-static void _signal_playlist_changed(MafwGstRenderer * self);
-static void _signal_transport_actions_property_changed(MafwGstRenderer * self);
-
-/*----------------------------------------------------------------------------
- Properties
- ----------------------------------------------------------------------------*/
-
-static void _set_error_policy(MafwGstRenderer *renderer, MafwRendererErrorPolicy policy);
-static MafwRendererErrorPolicy _get_error_policy(MafwGstRenderer *renderer);
-
-static void mafw_gst_renderer_set_property(MafwExtension *self, const gchar *key,
- const GValue *value);
-static void mafw_gst_renderer_get_property(MafwExtension *self, const gchar *key,
- MafwExtensionPropertyCallback callback,
- gpointer user_data);
-
-/*----------------------------------------------------------------------------
- Metadata
- ----------------------------------------------------------------------------*/
-
-static void _notify_metadata(MafwSource *cb_source,
- const gchar *cb_object_id,
- GHashTable *cb_metadata,
- gpointer cb_user_data,
- const GError *cb_error);
-
-/*----------------------------------------------------------------------------
- Notification operations
- ----------------------------------------------------------------------------*/
-
-static void _notify_play(MafwGstRendererWorker *worker, gpointer owner);
-static void _notify_pause(MafwGstRendererWorker *worker, gpointer owner);
-static void _notify_seek(MafwGstRendererWorker *worker, gpointer owner);
-static void _notify_buffer_status(MafwGstRendererWorker *worker, gpointer owner,
- gdouble percent);
-static void _notify_eos(MafwGstRendererWorker *worker, gpointer owner);
-static void _error_handler(MafwGstRendererWorker *worker, gpointer owner,
- const GError *error);
-
-#ifdef HAVE_CONIC
-/*----------------------------------------------------------------------------
- Connection
- ----------------------------------------------------------------------------*/
-
-static void _connection_init(MafwGstRenderer *renderer);
-#endif
-
-/*----------------------------------------------------------------------------
- Plugin initialization
- ----------------------------------------------------------------------------*/
-
-/*
- * Registers the plugin descriptor making this plugin available to the
- * framework and applications
- */
-G_MODULE_EXPORT MafwPluginDescriptor mafw_gst_renderer_plugin_description = {
- { .name = MAFW_GST_RENDERER_PLUGIN_NAME },
- .initialize = mafw_gst_renderer_initialize,
- .deinitialize = mafw_gst_renderer_deinitialize,
-};
-
-static gboolean mafw_gst_renderer_initialize(MafwRegistry *registry,
- GError **error)
-{
- MafwGstRenderer *self;
-
- g_assert(registry != NULL);
- self = MAFW_GST_RENDERER(mafw_gst_renderer_new(registry));
- mafw_registry_add_extension(registry, MAFW_EXTENSION(self));
-
- return TRUE;
-}
-
-static void mafw_gst_renderer_deinitialize(GError **error)
-{
-}
-
-/*----------------------------------------------------------------------------
- GObject initialization
- ----------------------------------------------------------------------------*/
-
-G_DEFINE_TYPE(MafwGstRenderer, mafw_gst_renderer, MAFW_TYPE_RENDERER);
-
-static void mafw_gst_renderer_class_init(MafwGstRendererClass *klass)
-{
- GObjectClass *gclass = NULL;
- MafwRendererClass *renderer_class = NULL;
- const gchar *preloaded_plugins[] = {"playback", "uridecodebin",
- "coreelements", "typefindfunctions", "dsp",
- "pulseaudio", "xvimagesink", NULL};
- gint i = 0;
- GObject *plugin;
-
- gclass = G_OBJECT_CLASS(klass);
- g_return_if_fail(gclass != NULL);
-
- renderer_class = MAFW_RENDERER_CLASS(klass);
- g_return_if_fail(renderer_class != NULL);
-
- /* GObject */
-
- gclass->dispose = mafw_gst_renderer_dispose;
- gclass->finalize = mafw_gst_renderer_finalize;
-
- /* Playback */
-
- renderer_class->play = mafw_gst_renderer_play;
- renderer_class->play_object = mafw_gst_renderer_play_object;
- renderer_class->stop = mafw_gst_renderer_stop;
- renderer_class->pause = mafw_gst_renderer_pause;
- renderer_class->resume = mafw_gst_renderer_resume;
- renderer_class->get_status = mafw_gst_renderer_get_status;
-
- /* Playlist operations */
-
- renderer_class->assign_playlist = mafw_gst_renderer_assign_playlist;
- renderer_class->next = mafw_gst_renderer_next;
- renderer_class->previous = mafw_gst_renderer_previous;
- renderer_class->goto_index = mafw_gst_renderer_goto_index;
-
- /* Playback position */
-
- renderer_class->set_position = mafw_gst_renderer_set_position;
- renderer_class->get_position = mafw_gst_renderer_get_position;
-
- /* Metadata */
-
- renderer_class->get_current_metadata =
- mafw_gst_renderer_get_current_metadata;
-
- /* Properties */
-
- MAFW_EXTENSION_CLASS(klass)->get_extension_property =
- (gpointer) mafw_gst_renderer_get_property;
- MAFW_EXTENSION_CLASS(klass)->set_extension_property =
- (gpointer) mafw_gst_renderer_set_property;
-
- gst_init(NULL, NULL);
- gst_pb_utils_init();
-
- /* Pre-load some common plugins */
- while (preloaded_plugins[i])
- {
- plugin = G_OBJECT(gst_plugin_load_by_name(preloaded_plugins[i]));
- if (plugin)
- g_object_unref(plugin);
- else
- g_debug("Can not load plugin: %s", preloaded_plugins[i]);
- i++;
- }
-}
-
-static void mafw_gst_renderer_init(MafwGstRenderer *self)
-{
- MafwGstRenderer *renderer = NULL;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- renderer = MAFW_GST_RENDERER(self);
- g_return_if_fail(renderer != NULL);
-
- mafw_extension_add_property(MAFW_EXTENSION(self), "volume", G_TYPE_UINT);
-#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
- mafw_extension_add_property(MAFW_EXTENSION(self), "mute", G_TYPE_BOOLEAN);
-#endif
- mafw_extension_add_property(MAFW_EXTENSION(self), "xid", G_TYPE_UINT);
- mafw_extension_add_property(MAFW_EXTENSION(self), "error-policy", G_TYPE_UINT);
- MAFW_EXTENSION_SUPPORTS_AUTOPAINT(self);
- MAFW_EXTENSION_SUPPORTS_COLORKEY(self);
-#ifdef HAVE_GDKPIXBUF
- mafw_extension_add_property(MAFW_EXTENSION(self),
- "current-frame-on-pause",
- G_TYPE_BOOLEAN);
-#endif
- mafw_extension_add_property(MAFW_EXTENSION(self),
- MAFW_PROPERTY_GST_RENDERER_TV_CONNECTED,
- G_TYPE_BOOLEAN);
- MAFW_EXTENSION_SUPPORTS_TRANSPORT_ACTIONS(self);
- renderer->media = g_new0(MafwGstRendererMedia, 1);
- renderer->media->seekability = SEEKABILITY_UNKNOWN;
- renderer->current_state = Stopped;
-
- renderer->playlist = NULL;
- renderer->iterator = NULL;
- renderer->seeking_to = -1;
- renderer->update_playcount_id = 0;
-
- self->worker = mafw_gst_renderer_worker_new(self);
-
- /* Set notification handlers for worker */
- renderer->worker->notify_play_handler = _notify_play;
- renderer->worker->notify_pause_handler = _notify_pause;
- renderer->worker->notify_seek_handler = _notify_seek;
- renderer->worker->notify_error_handler = _error_handler;
- renderer->worker->notify_eos_handler = _notify_eos;
- renderer->worker->notify_buffer_status_handler = _notify_buffer_status;
-
- renderer->states = g_new0 (MafwGstRendererState*, _LastMafwPlayState);
- renderer->states[Stopped] =
- MAFW_GST_RENDERER_STATE(mafw_gst_renderer_state_stopped_new(self));
- renderer->states[Transitioning] =
- MAFW_GST_RENDERER_STATE(
- mafw_gst_renderer_state_transitioning_new(self));
- renderer->states[Playing] =
- MAFW_GST_RENDERER_STATE(mafw_gst_renderer_state_playing_new(self));
- renderer->states[Paused] =
- MAFW_GST_RENDERER_STATE(mafw_gst_renderer_state_paused_new(self));
-
- renderer->current_state = Stopped;
- renderer->resume_playlist = FALSE;
- renderer->playback_mode = MAFW_GST_RENDERER_MODE_PLAYLIST;
-
-#ifdef HAVE_CONIC
- renderer->connected = FALSE;
- renderer->connection = NULL;
-
- _connection_init(renderer);
-#endif
- renderer->gconf_client = gconf_client_get_default();
- gconf_client_add_dir(renderer->gconf_client, GCONF_OSSO_AF,
- GCONF_CLIENT_PRELOAD_ONELEVEL, &error);
- if (error) {
- g_warning("%s", error->message);
- g_error_free(error);
- error = NULL;
- }
-
- gconf_client_notify_add(renderer->gconf_client,
- GCONF_BATTERY_COVER_OPEN,
- (GConfClientNotifyFunc) _battery_cover_open_cb,
- renderer,
- NULL, &error);
-
- if (error) {
- g_warning("%s", error->message);
- g_error_free(error);
- }
-
- gconf_client_add_dir(renderer->gconf_client,
- GCONF_MAFW_GST_SUBTITLES_RENDERER,
- GCONF_CLIENT_PRELOAD_ONELEVEL,
- &error);
- if (error) {
- g_warning("%s", error->message);
- g_error_free(error);
- error = NULL;
- }
-
- gconf_client_notify_add(renderer->gconf_client,
- GCONF_MAFW_GST_SUBTITLES_RENDERER "/autoload_subtitles",
- (GConfClientNotifyFunc) _autoload_subtitles_changed_cb,
- renderer,
- NULL, &error);
- if (error) {
- g_warning("%s", error->message);
- g_error_free(error);
- }
-
- gconf_client_notify_add(renderer->gconf_client,
- GCONF_MAFW_GST_SUBTITLES_RENDERER "/subtitle_encoding",
- (GConfClientNotifyFunc) _subtitle_font_changed_cb,
- renderer,
- NULL, &error);
- if (error) {
- g_warning("%s", error->message);
- g_error_free(error);
- }
-
- gconf_client_notify_add(renderer->gconf_client,
- GCONF_MAFW_GST_SUBTITLES_RENDERER "/subtitle_font",
- (GConfClientNotifyFunc) _subtitle_font_changed_cb,
- renderer,
- NULL, &error);
- if (error) {
- g_warning("%s", error->message);
- g_error_free(error);
- }
-
- if (self->worker->pipeline) {
- gconf_client_notify(renderer->gconf_client,
- GCONF_MAFW_GST_SUBTITLES_RENDERER "/autoload_subtitles");
-
- gconf_client_notify(renderer->gconf_client,
- GCONF_MAFW_GST_SUBTITLES_RENDERER "/subtitle_encoding");
-
- gconf_client_notify(renderer->gconf_client,
- GCONF_MAFW_GST_SUBTITLES_RENDERER "/subtitle_font");
- }
-
- if (gnome_vfs_init()) {
- GnomeVFSVolumeMonitor *monitor = gnome_vfs_get_volume_monitor();
- g_signal_connect(monitor, "volume-pre-unmount",
- G_CALLBACK(_volume_pre_unmount_cb), renderer);
- } else {
- g_warning("Failed to initialize gnome-vfs");
- }
-}
-
-static void mafw_gst_renderer_dispose(GObject *object)
-{
- MafwGstRenderer *renderer;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(object));
-
- renderer = MAFW_GST_RENDERER(object);
-
- if (renderer->worker != NULL) {
- mafw_gst_renderer_worker_exit(renderer->worker);
- renderer->seek_pending = FALSE;
- g_free(renderer->worker);
- renderer->worker = NULL;
- }
-
- if (renderer->registry != NULL) {
- g_object_unref(renderer->registry);
- renderer->registry = NULL;
- }
-
- if (renderer->states != NULL) {
- guint i = 0;
-
- for (i = 0; i < _LastMafwPlayState; i++) {
- if (renderer->states[i] != NULL)
- g_object_unref(renderer->states[i]);
- }
- g_free(renderer->states);
- renderer->states = NULL;
- }
-
- if (renderer->hal_ctx != NULL) {
- libhal_device_remove_property_watch(renderer->hal_ctx,
- HAL_VIDEOOUT_UDI,
- NULL);
- libhal_ctx_shutdown(renderer->hal_ctx, NULL);
- libhal_ctx_free(renderer->hal_ctx);
- }
-
-#ifdef HAVE_CONIC
- if (renderer->connection != NULL) {
- g_object_unref(renderer->connection);
- renderer->connection = NULL;
- }
-#endif
-
- if (renderer->gconf_client != NULL) {
- g_object_unref(renderer->gconf_client);
- renderer->gconf_client = NULL;
- }
-
- G_OBJECT_CLASS(mafw_gst_renderer_parent_class)->dispose(object);
-}
-
-static void mafw_gst_renderer_finalize(GObject *object)
-{
- MafwGstRenderer *self = (MafwGstRenderer*) object;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- mafw_gst_renderer_clear_media(self);
-
- if (self->media)
- {
- g_free(self->media);
- self->media = NULL;
- }
-
- G_OBJECT_CLASS(mafw_gst_renderer_parent_class)->finalize(object);
-}
-
-/**
- * mafw_gst_renderer_new:
- * @registry: The registry that owns this renderer.
- *
- * Creates a new MafwGstRenderer object
- */
-GObject *mafw_gst_renderer_new(MafwRegistry* registry)
-{
- GObject* object;
- LibHalContext *ctx;
- DBusConnection *conn;
- DBusError err;
- char **jackets;
- char **jack;
- gint num_jacks;
-
- object = g_object_new(MAFW_TYPE_GST_RENDERER,
- "uuid", MAFW_GST_RENDERER_UUID,
- "name", MAFW_GST_RENDERER_NAME,
- "plugin", MAFW_GST_RENDERER_PLUGIN_NAME,
- NULL);
- g_assert(object != NULL);
- MAFW_GST_RENDERER(object)->registry = g_object_ref(registry);
-
- /* Set default error policy */
- MAFW_GST_RENDERER(object)->error_policy =
- MAFW_RENDERER_ERROR_POLICY_CONTINUE;
-
- MAFW_GST_RENDERER(object)->tv_connected = FALSE;
-
- /* Setup hal connection for reacting usb cable connected event */
- dbus_error_init(&err);
- conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
-
- if (dbus_error_is_set(&err)) {
- g_warning("Couldn't setup HAL connection: %s", err.message);
- dbus_error_free(&err);
-
- goto err1;
- }
- ctx = libhal_ctx_new();
- libhal_ctx_set_dbus_connection(ctx, conn);
- libhal_ctx_set_user_data(ctx, object);
-
- if (libhal_ctx_init(ctx, &err) == FALSE) {
- if (dbus_error_is_set(&err)) {
- g_warning("Could not initialize hal: %s", err.message);
- dbus_error_free(&err);
- } else {
- g_warning("Could not initialize hal");
- }
- goto err2;
- }
-
- libhal_device_add_property_watch(ctx, HAL_VIDEOOUT_UDI, &err);
-
- if (dbus_error_is_set(&err)) {
- g_warning("Could not start watching usb device: %s",
- err.message);
- dbus_error_free(&err);
-
- goto err3;
- }
- libhal_ctx_set_device_property_modified(ctx, _property_modified);
-
- /* Initializes blanking policy */
- jackets = libhal_find_device_by_capability(ctx,
- "input.jack.video-out",
- &num_jacks, NULL);
- if (jackets != NULL) {
- jack = jackets;
- while (*jack) {
- if (_tv_out_is_connected(ctx, *jack)) {
- MAFW_GST_RENDERER(object)->tv_connected = TRUE;
- break;
- }
- jack++;
- }
-
- blanking_control(*jack == NULL);
- libhal_free_string_array(jackets);
- }
-
- MAFW_GST_RENDERER(object)->hal_ctx = ctx;
-
- return object;
-err3:
- libhal_ctx_shutdown(ctx, NULL);
-err2:
- libhal_ctx_free(ctx);
-err1:
- return object;
-}
-
-/**
- * mafw_gst_renderer_error_quark:
- *
- * Fetches the quark representing the domain of the errors in the
- * gst renderer
- *
- * Return value: a quark identifying the error domain of the
- * #MafwGstRenderer objects.
- *
- **/
-GQuark mafw_gst_renderer_error_quark(void)
-{
- return g_quark_from_static_string("mafw-gst-renderer-error-quark");
-}
-
-void mafw_gst_renderer_set_playback_mode(MafwGstRenderer *self,
- MafwGstRendererPlaybackMode mode)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
- self->playback_mode = mode;
-}
-
-MafwGstRendererPlaybackMode mafw_gst_renderer_get_playback_mode(
- MafwGstRenderer *self)
-{
- g_return_val_if_fail(MAFW_IS_GST_RENDERER(self),
- MAFW_GST_RENDERER_MODE_STANDALONE);
- return self->playback_mode;
-}
-
-/*----------------------------------------------------------------------------
- Set Media
- ----------------------------------------------------------------------------*/
-
-static MafwSource* _get_source(MafwGstRenderer *renderer,
- const gchar *object_id)
-{
- MafwSource* source;
- gchar* sourceid = NULL;
-
- g_assert(object_id != NULL);
-
- /* Attempt to find a source that provided the object ID */
- mafw_source_split_objectid(object_id, &sourceid, NULL);
- source = MAFW_SOURCE(mafw_registry_get_extension_by_uuid(
- renderer->registry, sourceid));
- g_free(sourceid);
-
- return source;
-}
-
-void mafw_gst_renderer_get_metadata(MafwGstRenderer* self,
- const gchar* objectid,
- GError **error)
-{
- MafwSource* source;
-
- g_assert(self != NULL);
-
- /*
- * Any error here is an error when trying to Play, so
- * it must be handled by error policy.
- * Problem: if we get an error here and we are not in
- * Transitioning yet (maybe we are still in Stopped state)
- * then the policy may move to next and stay Stopped (instead of
- * trying to play), so errors need to be handled by the policy
- * in an idle callback, so that any error that may happen here
- * is not processed until we have moved to Transitioning state
- */
-
- source = _get_source(self, objectid);
- if (source != NULL)
- {
- /* List of metadata keys that we are interested in when going to
- Transitioning state */
- static const gchar * const keys[] =
- { MAFW_METADATA_KEY_URI,
- MAFW_METADATA_KEY_IS_SEEKABLE,
- MAFW_METADATA_KEY_DURATION,
- NULL };
-
- /* Source found, get metadata */
- mafw_source_get_metadata(source, objectid,
- keys,
- _notify_metadata,
- self);
-
- }
- else
- {
- /* This is a playback error: execute error policy */
- MafwGstRendererErrorClosure *error_closure;
- error_closure = g_new0(MafwGstRendererErrorClosure, 1);
- error_closure->renderer = self;
- g_set_error (&(error_closure->error),
- MAFW_EXTENSION_ERROR,
- MAFW_EXTENSION_ERROR_EXTENSION_NOT_AVAILABLE,
- "Unable to find source for current object ID");
- g_idle_add(mafw_gst_renderer_manage_error_idle, error_closure);
- }
-}
-
-void mafw_gst_renderer_set_object(MafwGstRenderer *self, const gchar *object_id)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer *) self;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
- g_return_if_fail(object_id != NULL);
-
- /* This is intended to be called only when using play_object(),
- * as for playlists we use set_media_playlist()
- */
-
- /* Stop any ongoing playback */
- mafw_gst_renderer_clear_media(renderer);
-
- /* Set new object */
- renderer->media->object_id = g_strdup(object_id);
-
- /* Signal media changed */
- _signal_media_changed(renderer);
-}
-
-
-/**
- * mafw_gst_renderer_clear_media:
- *
- * @renderer A #MafwGstRenderer whose media to clear
- *
- * Clears & frees the renderer's current media details
- **/
-void mafw_gst_renderer_clear_media(MafwGstRenderer *self)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
- g_return_if_fail(self->media != NULL);
-
- g_free(self->media->object_id);
- self->media->object_id = NULL;
-
- g_free(self->media->uri);
- self->media->uri = NULL;
-
- g_free(self->media->title);
- self->media->title = NULL;
-
- g_free(self->media->artist);
- self->media->artist = NULL;
-
- g_free(self->media->album);
- self->media->album = NULL;
-
- self->media->duration = 0;
- self->media->position = 0;
-}
-
-
-/**
- * mafw_gst_renderer_set_media_playlist:
- *
- * @self A #MafwGstRenderer, whose media to set
- *
- * Set current media from the renderer's playlist, using the current playlist index.
- **/
-void mafw_gst_renderer_set_media_playlist(MafwGstRenderer* self)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- /* Get rid of old media details */
- mafw_gst_renderer_clear_media(self);
-
- if (self->playlist != NULL &&
- mafw_playlist_iterator_get_size(self->iterator, NULL) > 0) {
- /* Get the current item from playlist */
- self->media->object_id =
- g_strdup(mafw_playlist_iterator_get_current_objectid(self->iterator));
- } else {
- self->media->object_id = NULL;
- }
-
- _signal_media_changed(self);
-}
-
-#ifdef HAVE_CONIC
-/*----------------------------------------------------------------------------
- Connection
- ----------------------------------------------------------------------------*/
-
-static void
-_con_ic_status_handler(ConIcConnection *conn, ConIcConnectionEvent *event,
- gpointer data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer *) data;
-
- g_assert(MAFW_IS_GST_RENDERER(renderer));
-
- renderer->connected =
- con_ic_connection_event_get_status(event) ==
- CON_IC_STATUS_CONNECTED;
-}
-
-static void
-_connection_init(MafwGstRenderer *renderer)
-{
- g_assert (MAFW_IS_GST_RENDERER(renderer));
-
- if (renderer->connection == NULL) {
- renderer->connection = con_ic_connection_new();
- renderer->connected = FALSE;
-
- g_assert(renderer->connection != NULL);
- }
-
- g_object_set(renderer->connection, "automatic-connection-events",
- TRUE, NULL);
- g_signal_connect(renderer->connection, "connection-event",
- G_CALLBACK (_con_ic_status_handler), renderer);
-
- con_ic_connection_connect(renderer->connection,
- CON_IC_CONNECT_FLAG_AUTOMATICALLY_TRIGGERED);
-}
-#endif
-
-/*----------------------------------------------------------------------------
- Hal callbacks
- ----------------------------------------------------------------------------*/
-
-static gboolean _tv_out_is_connected(LibHalContext *ctx, const char *udi)
-{
- gboolean is_tv_out_jack = FALSE;
- char **jack_types;
- char **jack;
-
- if (udi == NULL) {
- return FALSE;
- }
-
- jack_types = libhal_device_get_property_strlist(ctx, udi,
- "input.jack.type",
- NULL);
- if (jack_types == NULL) {
- return FALSE;
- }
-
- jack = jack_types;
- while (*jack) {
- if (strcmp(*jack, "video-out") == 0) {
- is_tv_out_jack = TRUE;
- break;
- } else {
- jack++;
- }
- }
-
- libhal_free_string_array(jack_types);
-
- return is_tv_out_jack;
-}
-
-static void _property_modified(LibHalContext *ctx, const char *udi,
- const char *key, dbus_bool_t is_removed,
- dbus_bool_t is_added)
-{
- MafwGstRenderer *renderer;
- gboolean connected;
- GValue value = { 0 };
-
- g_debug("HAL property modified! jack changed\n");
- connected = _tv_out_is_connected(ctx, udi);
- renderer = MAFW_GST_RENDERER(libhal_ctx_get_user_data(ctx));
- if (renderer->tv_connected != connected) {
- /* Notify the change */
- renderer->tv_connected = connected;
- g_value_init(&value, G_TYPE_BOOLEAN);
- g_value_set_boolean(&value, renderer->tv_connected);
- mafw_extension_emit_property_changed(
- MAFW_EXTENSION(renderer),
- MAFW_PROPERTY_GST_RENDERER_TV_CONNECTED,
- &value);
- g_value_unset(&value);
- }
- blanking_control(connected == FALSE);
-}
-
-/*----------------------------------------------------------------------------
- GConf notifications
- ----------------------------------------------------------------------------*/
-
-static void _battery_cover_open_cb(GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- MafwGstRenderer *renderer)
-{
- GConfValue *value = NULL;
- gboolean is_cover_open;
-
- value = gconf_entry_get_value(entry);
- is_cover_open = gconf_value_get_bool(value);
-
- if (is_cover_open) {
- /* External mmc could be removed!. */
- const gchar *emmc_path = g_getenv("MMC_MOUNTPOINT");
-
- mafw_gst_renderer_state_handle_pre_unmount(
- MAFW_GST_RENDERER_STATE(
- renderer->states[renderer->current_state]),
- emmc_path);
- }
-}
-
-static void _autoload_subtitles_changed_cb(GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- MafwGstRenderer *renderer)
-{
- GConfValue *value = NULL;
- gboolean enabled = FALSE;
-
- value = gconf_entry_get_value(entry);
- if (value == NULL)
- return;
-
- enabled = gconf_value_get_bool(value);
-
- if (enabled)
- renderer->worker->subtitles.enabled = TRUE;
- else
- renderer->worker->subtitles.enabled = FALSE;
-}
-
-static void _subtitle_font_changed_cb(GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- MafwGstRenderer *renderer)
-{
- const gchar *key = NULL;
- GConfValue *value = NULL;
- const gchar *str_value = NULL;
-
- key = gconf_entry_get_key(entry);
-
- /* Only key without absolute path is required */
- key += strlen(GCONF_MAFW_GST_SUBTITLES_RENDERER) + 1;
-
- value = gconf_entry_get_value(entry);
- if (value)
- str_value = gconf_value_get_string(value);
- else
- str_value = NULL;
-
- if (strcmp(key, "subtitle_font") == 0) {
- if (renderer->worker->subtitles.font)
- g_free(renderer->worker->subtitles.font);
-
- if (str_value)
- renderer->worker->subtitles.font = g_strdup(str_value);
- else
- renderer->worker->subtitles.font = NULL;
- } else if (strcmp(key, "subtitle_encoding") == 0) {
- if (renderer->worker->subtitles.encoding)
- g_free(renderer->worker->subtitles.encoding);
-
- if (str_value)
- renderer->worker->subtitles.encoding = g_strdup(str_value);
- else
- renderer->worker->subtitles.encoding = NULL;
- } else {
- g_warning("Wrong %s key, %s", GCONF_MAFW_GST_SUBTITLES_RENDERER, key);
- }
-}
-
-/*----------------------------------------------------------------------------
- Gnome VFS notifications
- ----------------------------------------------------------------------------*/
-
-static void _volume_pre_unmount_cb(GnomeVFSVolumeMonitor *monitor,
- GnomeVFSVolume *volume,
- MafwGstRenderer *renderer)
-{
- gchar *location = gnome_vfs_volume_get_activation_uri(volume);
- if (!location) {
- return;
- }
-
- mafw_gst_renderer_state_handle_pre_unmount(
- MAFW_GST_RENDERER_STATE(
- renderer->states[renderer->current_state]),
- location);
-
- g_free(location);
-}
-
-/*----------------------------------------------------------------------------
- Signals
- ----------------------------------------------------------------------------*/
-
-
-/**
- * _signal_state_changed:
- * @self: A #MafwGstRenderer
- *
- * Signals state_changed to all UIs
- **/
-static void _signal_state_changed(MafwGstRenderer * self)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_signal_emit_by_name(MAFW_RENDERER(self),
- "state-changed", self->current_state);
-}
-
-/**
- * _signal_playlist_changed:
- * @self: A #MafwGstRenderer
- *
- * Signals playlist update to all UIs
- **/
-static void _signal_playlist_changed(MafwGstRenderer * self)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_signal_emit_by_name(MAFW_RENDERER(self),
- "playlist-changed", self->playlist);
-}
-
-/**
- * _signal_media_changed:
- * @self: A #MafwGstRenderer
- *
- * Signals media_changed to all UIs
- **/
-static void _signal_media_changed(MafwGstRenderer *self)
-{
-
- MafwGstRendererPlaybackMode mode;
- gint index;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- mode = mafw_gst_renderer_get_playback_mode(MAFW_GST_RENDERER(self));
- if ((mode == MAFW_GST_RENDERER_MODE_STANDALONE) ||
- (self->iterator == NULL)) {
- index = -1;
- } else {
- index = mafw_playlist_iterator_get_current_index(self->iterator);
- }
-
- g_signal_emit_by_name(MAFW_RENDERER(self),
- "media-changed",
- index,
- self->media->object_id);
-}
-
-/**
- * _signal_transport_actions_property_changed:
- * @self: A #MafwGstRenderer
- *
- * Signals transport_actions property_changed to all UIs
- **/
-static void _signal_transport_actions_property_changed(MafwGstRenderer * self)
-{
- GValue *value;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- value = mafw_gst_renderer_state_get_property_value(
- MAFW_GST_RENDERER_STATE(
- self->states[self->current_state]),
- MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS);
-
- if (value) {
- mafw_extension_emit_property_changed(
- MAFW_EXTENSION(self),
- MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS,
- value);
- g_value_unset(value);
- g_free(value);
- }
-}
-
-
-/*----------------------------------------------------------------------------
- State pattern support
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_set_state(MafwGstRenderer *self, MafwPlayState state)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- self->current_state = state;
- _signal_state_changed(self);
- _signal_transport_actions_property_changed(self);
-}
-
-void mafw_gst_renderer_play(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer*) self;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- mafw_gst_renderer_state_play(
- MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
- &error);
-
- if (callback != NULL)
- callback(self, user_data, error);
- if (error)
- g_error_free(error);
-}
-
-void mafw_gst_renderer_play_object(MafwRenderer *self,
- const gchar *object_id,
- MafwRendererPlaybackCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer*) self;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
- g_return_if_fail(object_id != NULL);
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- mafw_gst_renderer_state_play_object(
- MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
- object_id,
- &error);
-
- if (callback != NULL)
- callback(self, user_data, error);
- if (error)
- g_error_free(error);
-}
-
-void mafw_gst_renderer_stop(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer *) self;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- renderer->play_failed_count = 0;
- mafw_gst_renderer_state_stop(
- MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
- &error);
-
- if (callback != NULL)
- callback(self, user_data, error);
- if (error)
- g_error_free(error);
-}
-
-
-void mafw_gst_renderer_pause(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer *) self;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- mafw_gst_renderer_state_pause(
- MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
- &error);
-
- if (callback != NULL)
- callback(self, user_data, error);
- if (error)
- g_error_free(error);
-}
-
-void mafw_gst_renderer_resume(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer *) self;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- mafw_gst_renderer_state_resume(
- MAFW_GST_RENDERER_STATE (renderer->states[renderer->current_state]),
- &error);
-
- if (callback != NULL)
- callback(self, user_data, error);
- if (error)
- g_error_free(error);
-}
-
-void mafw_gst_renderer_next(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer *) self;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- renderer->play_failed_count = 0;
- mafw_gst_renderer_state_next(
- MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
- &error);
-
- if (callback != NULL)
- callback(self, user_data, error);
- if (error)
- g_error_free(error);
-}
-
-void mafw_gst_renderer_previous(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer *) self;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- renderer->play_failed_count = 0;
- mafw_gst_renderer_state_previous(
- MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
- &error);
-
- if (callback != NULL)
- callback(self, user_data, error);
- if (error)
- g_error_free(error);
-}
-
-void mafw_gst_renderer_goto_index(MafwRenderer *self, guint index,
- MafwRendererPlaybackCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer *) self;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- renderer->play_failed_count = 0;
- mafw_gst_renderer_state_goto_index(
- MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
- index,
- &error);
-
- if (callback != NULL)
- callback(self, user_data, error);
- if (error)
- g_error_free(error);
-}
-
-void mafw_gst_renderer_get_position(MafwRenderer *self, MafwRendererPositionCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer;
- gint pos;
- GError *error = NULL;
-
- g_return_if_fail(callback != NULL);
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- renderer = MAFW_GST_RENDERER(self);
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- mafw_gst_renderer_state_get_position(
- MAFW_GST_RENDERER_STATE (renderer->states[renderer->current_state]),
- &pos,
- &error);
-
- callback(self, pos, user_data, error);
- if (error)
- g_error_free(error);
-}
-
-void mafw_gst_renderer_set_position(MafwRenderer *self, MafwRendererSeekMode mode,
- gint seconds, MafwRendererPositionCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer *) self;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- mafw_gst_renderer_state_set_position(
- MAFW_GST_RENDERER_STATE (renderer->states[renderer->current_state]),
- mode,
- seconds,
- &error);
-
- if (callback != NULL)
- callback(self, seconds, user_data, error);
- if (error)
- g_error_free(error);
-}
-
-gboolean mafw_gst_renderer_manage_error_idle(gpointer data)
-{
- MafwGstRendererErrorClosure *mec = (MafwGstRendererErrorClosure *) data;
-
- mafw_gst_renderer_manage_error(mec->renderer, mec->error);
- if (mec->error)
- g_error_free(mec->error);
- g_free(mec);
-
- return FALSE;
-}
-
-static void _run_error_policy(MafwGstRenderer *self, const GError *in_err,
- GError **out_err)
-{
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- gboolean play_next = FALSE;
-
- /* Check what to do on error */
- if (in_err->code == MAFW_EXTENSION_ERROR_OUT_OF_MEMORY) {
- play_next = FALSE;
- } else {
- MafwGstRendererPlaybackMode mode;
-
- mode = mafw_gst_renderer_get_playback_mode(self);
-
- if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST) {
- /* In playlist mode we try to play next if
- error policy suggests so */
- play_next =
- (_get_error_policy(self) ==
- MAFW_RENDERER_ERROR_POLICY_CONTINUE);
- } else {
- /* In standalone mode, then switch back to playlist
- mode and resume if necessary or move to Stopped
- otherwise */
- mafw_gst_renderer_set_playback_mode(
- self, MAFW_GST_RENDERER_MODE_PLAYLIST);
- mafw_gst_renderer_set_media_playlist(self);
- if (self->resume_playlist) {
- mafw_gst_renderer_play(MAFW_RENDERER(self),
- NULL, NULL);
- } else {
- mafw_gst_renderer_worker_stop(self->worker);
- mafw_gst_renderer_set_state(self, Stopped);
- }
- if (out_err) *out_err = g_error_copy(in_err);
-
- /* Bail out, he have already managed the error
- for the case of standalone mode */
- return;
- }
- }
-
- if (play_next) {
- if (self->playlist){
- MafwPlaylistIteratorMovementResult result;
-
- result = mafw_playlist_iterator_move_to_next(self->iterator,
- NULL);
- self->play_failed_count++;
-
- if (mafw_playlist_iterator_get_size(self->iterator,
- NULL) <=
- self->play_failed_count)
- {
- mafw_gst_renderer_state_stop(
- MAFW_GST_RENDERER_STATE(self->states[self->current_state]),
- NULL);
- self->play_failed_count = 0;
- mafw_gst_renderer_set_media_playlist(self);
- } else if (result !=
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK) {
- mafw_playlist_iterator_reset(self->iterator, NULL);
- mafw_gst_renderer_set_media_playlist(self);
- mafw_gst_renderer_stop(MAFW_RENDERER(self), NULL, NULL);
- } else {
- mafw_gst_renderer_set_media_playlist(self);
- mafw_gst_renderer_play(MAFW_RENDERER(self), NULL, NULL);
- }
-
- if (out_err) *out_err = g_error_copy(in_err);
- }
- } else {
- /* We cannot move to next in the playlist or decided
- we do not want to do it, just stop on error */
- mafw_gst_renderer_stop(MAFW_RENDERER(self), NULL, NULL);
- if (out_err) *out_err = g_error_copy(in_err);
- }
-}
-
-static void _metadata_set_cb(MafwSource *self, const gchar *object_id,
- const gchar **failed_keys, gpointer user_data,
- const GError *error)
-{
- if (error != NULL) {
- g_debug("Ignoring error received when setting metadata: "
- "%s (%d): %s", g_quark_to_string(error->domain),
- error->code, error->message);
- } else {
- g_debug("Metadata set correctly");
- }
-}
-
-/**
- * _update_playcount_metadata_cb:
- * @cb_source: The #MafwSource that sent the metadata results
- * @cb_object_id: The object ID, whose metadata results were received
- * @cb_metadata: GHashTable containing metadata key-value pairs
- * @cb_user_data: Optional user data pointer (self)
- * @cb_error: Set if any errors occurred during metadata browsing
- *
- * Receives the results of a metadata request about the playcount. It increases
- * it, or sets to 1, and sets the metadata to that.
- */
-static void _update_playcount_metadata_cb (MafwSource *cb_source,
- const gchar *cb_object_id,
- GHashTable *cb_metadata,
- gpointer cb_user_data,
- const GError *cb_error)
-{
- GValue *curval = NULL;
- gint curplaycount = -1;
- GHashTable *mdata = cb_user_data;
-
- if (cb_error == NULL) {
- if (cb_metadata)
- curval = mafw_metadata_first(cb_metadata,
- MAFW_METADATA_KEY_PLAY_COUNT);
- if (curval && !G_VALUE_HOLDS(curval, G_TYPE_INT))
- goto set_data;
- if (curval)
- {
- curplaycount = g_value_get_int(curval);
- curplaycount++;
- }
- else
- { /* Playing at first time, or not supported... */
- curplaycount = 1;
- }
- if (!mdata)
- mdata = mafw_metadata_new();
- mafw_metadata_add_int(mdata,
- MAFW_METADATA_KEY_PLAY_COUNT,
- curplaycount);
-
- } else {
- g_warning("_playcount_metadata received an error: "
- "%s (%d): %s", g_quark_to_string(cb_error->domain),
- cb_error->code, cb_error->message);
- if (mdata)
- g_hash_table_unref(mdata);
- return;
- }
-set_data:
-
- if (mdata)
- {
- mafw_source_set_metadata(cb_source, cb_object_id, mdata,
- _metadata_set_cb, NULL);
- g_hash_table_unref(mdata);
- }
-}
-
-/**
- * mafw_gst_renderer_add_lastplayed:
- * @mdata: Exisiting mdata, or NULL
- *
- * Sets the MAFW_METADATA_KEY_LAST_PLAYED metadata in the given metadata-table,
- * or creates a new metadata-table, and sets the current time there.
- */
-static GHashTable *mafw_gst_renderer_add_lastplayed(GHashTable *mdata)
-{
- GHashTable *metadata;
- GTimeVal timeval;
-
-
- if (!mdata)
- metadata = mafw_metadata_new();
- else
- metadata = mdata;
-
-
-
- g_get_current_time(&timeval);
-
- mafw_metadata_add_long(metadata,
- MAFW_METADATA_KEY_LAST_PLAYED,
- timeval.tv_sec);
- return metadata;
-}
-
-/**
- * mafw_gst_renderer_increase_playcount:
- * @self: Gst renderer
- * @object_id: The object ID of the touched object
- * @mdat: Existing metadatas to add the playcount to, or NULL
- *
- * Increases the playcount of the given object.
- */
-static void mafw_gst_renderer_increase_playcount(MafwGstRenderer* self,
- const gchar *object_id, GHashTable *mdat)
-{
- MafwSource* source;
-
- g_assert(self != NULL);
- source = _get_source(self, object_id);
- if (source != NULL)
- {
- static const gchar * const keys[] =
- { MAFW_METADATA_KEY_PLAY_COUNT, NULL };
-
- mafw_source_get_metadata(source, object_id,
- keys,
- _update_playcount_metadata_cb,
- mdat);
-
- }
-}
-
-/**
- * mafw_gst_renderer_update_stats:
- * @data: user data
- *
- * Updates both playcount and lastplayed after a while.
- **/
-gboolean mafw_gst_renderer_update_stats(gpointer data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer *) data;
-
- /* Update stats only for audio content */
- if (renderer->media->object_id &&
- !renderer->worker->media.has_visual_content) {
- GHashTable *mdata = mafw_gst_renderer_add_lastplayed(NULL);
- mafw_gst_renderer_increase_playcount(renderer,
- renderer->media->object_id,
- mdata);
- }
- renderer->update_playcount_id = 0;
- return FALSE;
-}
-
-void mafw_gst_renderer_update_source_duration(MafwGstRenderer *renderer,
- gint duration)
-{
- GHashTable *metadata;
- MafwSource* source;
-
- source = _get_source(renderer, renderer->media->object_id);
- g_return_if_fail(source != NULL);
-
- renderer->media->duration = duration;
-
- g_debug("updated source duration to %d", duration);
-
- metadata = mafw_metadata_new();
- mafw_metadata_add_int(metadata, MAFW_METADATA_KEY_DURATION, duration);
-
- mafw_source_set_metadata(source, renderer->media->object_id, metadata,
- _metadata_set_cb, NULL);
- g_hash_table_unref(metadata);
-}
-
-/**
- * _notify_metadata:
- * @source: The #MafwSource that sent the metadata results
- * @objectid: The object ID, whose metadata results were received
- * @metadata: GHashTable containing metadata key-value pairs
- * @userdata: Optional user data pointer (self)
- * @error: Set if any errors occurred during metadata browsing
- *
- * Receives the results of a metadata request.
- */
-static void _notify_metadata (MafwSource *cb_source,
- const gchar *cb_object_id,
- GHashTable *cb_metadata,
- gpointer cb_user_data,
- const GError *cb_error)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer*) cb_user_data;
- GError *mafw_error = NULL;
- GError *error = NULL;
- GValue *mval;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(renderer));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- g_debug("running _notify_metadata...");
-
- mval = mafw_metadata_first(cb_metadata, MAFW_METADATA_KEY_URI);
-
- if (cb_error == NULL && mval != NULL) {
- mafw_gst_renderer_state_notify_metadata(
- MAFW_GST_RENDERER_STATE(
- renderer->states[renderer->current_state]),
- cb_object_id,
- cb_metadata,
- &error);
- }
- else {
- g_set_error(&mafw_error,
- MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_URI_NOT_AVAILABLE, "%s",
- cb_error ? cb_error->message : "URI not available");
- mafw_gst_renderer_manage_error(renderer, mafw_error);
- g_error_free(mafw_error);
- }
-}
-
-static void _notify_play(MafwGstRendererWorker *worker, gpointer owner)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer*) owner;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(renderer));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- g_debug("running _notify_play...");
-
- mafw_gst_renderer_state_notify_play(renderer->states[renderer->current_state],
- &error);
-
- if (error != NULL) {
- g_signal_emit_by_name(MAFW_EXTENSION (renderer), "error",
- error->domain,
- error->code,
- error->message);
- g_error_free (error);
- }
-}
-
-static void _notify_pause(MafwGstRendererWorker *worker, gpointer owner)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer*) owner;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER (renderer));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- mafw_gst_renderer_state_notify_pause(renderer->states[renderer->current_state],
- &error);
-
- if (error != NULL) {
- g_signal_emit_by_name(MAFW_EXTENSION (renderer), "error",
- error->domain, error->code,
- error->message);
- g_error_free(error);
- }
-}
-
-static void _notify_buffer_status (MafwGstRendererWorker *worker,
- gpointer owner,
- gdouble percent)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer*) owner;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(renderer));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- mafw_gst_renderer_state_notify_buffer_status(
- renderer->states[renderer->current_state],
- percent,
- &error);
-
- if (error != NULL) {
- g_signal_emit_by_name(MAFW_EXTENSION (renderer), "error",
- error->domain, error->code,
- error->message);
- g_error_free(error);
- }
-}
-
-static void _notify_seek(MafwGstRendererWorker *worker, gpointer owner)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer*) owner;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(renderer));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- mafw_gst_renderer_state_notify_seek(renderer->states[renderer->current_state],
- &error);
-
- if (error != NULL) {
- g_signal_emit_by_name(MAFW_EXTENSION(renderer), "error",
- error->domain, error->code,
- error->message);
- g_error_free(error);
- }
-}
-
-static void _playlist_changed_handler(MafwPlaylistIterator *iterator,
- gboolean clip_changed, GQuark domain,
- gint code, const gchar *message,
- gpointer user_data)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer*) user_data;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(renderer));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- /* We update the current index and media here, for this is
- the same for all the states. Then we delegate in the state
- to finish the task (for example, start playback if needed) */
-
- if (renderer->playlist == NULL) {
- g_critical("Got iterator:contents-changed but renderer has no" \
- "playlist assigned!. Skipping...");
- return;
- }
-
- if (domain != 0) {
- g_signal_emit_by_name(MAFW_EXTENSION(renderer), "error",
- domain, code, message);
- } else {
- GError *error = NULL;
- MafwGstRendererPlaybackMode mode;
-
- mode = mafw_gst_renderer_get_playback_mode(renderer);
-
- /* Only in non-playobject mode */
- if (clip_changed && mode == MAFW_GST_RENDERER_MODE_PLAYLIST)
- mafw_gst_renderer_set_media_playlist(renderer);
-
- /* We let the state know if the current clip has changed as
- result of this operation, so it can do its work */
- mafw_gst_renderer_state_playlist_contents_changed_handler(
- renderer->states[renderer->current_state],
- clip_changed,
- &error);
-
- if (error != NULL) {
- g_signal_emit_by_name(MAFW_EXTENSION(renderer), "error",
- error->domain, error->code,
- error->message);
- g_error_free(error);
- }
- }
-}
-
-static void _error_handler(MafwGstRendererWorker *worker, gpointer owner,
- const GError *error)
-{
- MafwGstRenderer *renderer = MAFW_GST_RENDERER(owner);
-
- mafw_gst_renderer_manage_error(renderer, error);
-}
-
-void mafw_gst_renderer_manage_error(MafwGstRenderer *self, const GError *error)
-{
- GError *new_err = NULL;
- GError *raise_error = NULL;
- GQuark new_err_domain = MAFW_RENDERER_ERROR;
- gint new_err_code = 0;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
-
- g_return_if_fail((self->states != 0) &&
- (self->current_state != _LastMafwPlayState) &&
- (self->states[self->current_state] != NULL));
-
- g_warning("Got error in renderer:\n\tdomain: %d, code: %d, message: %s",
- error->domain, error->code, error->message);
-
- /* Get a MAFW error */
- if (error->domain == GST_RESOURCE_ERROR) {
- /* handle RESOURCE errors */
- switch (error->code) {
- case GST_RESOURCE_ERROR_READ:
- if (is_current_uri_stream(self)) {
-#ifdef HAVE_CONIC
- if (self->connected) {
- new_err_code = MAFW_RENDERER_ERROR_STREAM_DISCONNECTED;
- } else {
- new_err_domain = MAFW_EXTENSION_ERROR;
- new_err_code = MAFW_EXTENSION_ERROR_NETWORK_DOWN;
- }
-#else
- /* Stream + cannot read resource ->
- disconnected */
- new_err_code = MAFW_RENDERER_ERROR_STREAM_DISCONNECTED;
-#endif
- } else {
- /* This shouldn't happen */
- /* Unknown RESOURCE error */
- new_err_domain = MAFW_EXTENSION_ERROR;
- new_err_code = MAFW_EXTENSION_ERROR_FAILED;
- }
- break;
- case GST_RESOURCE_ERROR_NOT_FOUND:
-#ifdef HAVE_CONIC
- if (!is_current_uri_stream(self) || self->connected) {
- new_err_code =
- MAFW_RENDERER_ERROR_INVALID_URI;
- } else {
- new_err_domain = MAFW_EXTENSION_ERROR;
- new_err_code = MAFW_EXTENSION_ERROR_NETWORK_DOWN;
- }
-#else
- new_err_code =
- MAFW_RENDERER_ERROR_INVALID_URI;
-#endif
- break;
- case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
- case GST_RESOURCE_ERROR_OPEN_READ:
-#ifdef HAVE_CONIC
- if (!is_current_uri_stream(self) || self->connected) {
- new_err_code =
- MAFW_RENDERER_ERROR_MEDIA_NOT_FOUND;
- } else {
- new_err_domain = MAFW_EXTENSION_ERROR;
- new_err_code = MAFW_EXTENSION_ERROR_NETWORK_DOWN;
- }
-#else
- new_err_code =
- MAFW_RENDERER_ERROR_MEDIA_NOT_FOUND;
-#endif
- break;
- case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
- new_err_domain = MAFW_EXTENSION_ERROR;
- new_err_code = MAFW_EXTENSION_ERROR_OUT_OF_MEMORY;
- break;
- case GST_RESOURCE_ERROR_WRITE:
- /* DSP renderers send ERROR_WRITE when they find
- corrupted data */
- new_err_code = MAFW_RENDERER_ERROR_CORRUPTED_FILE;
- break;
- case GST_RESOURCE_ERROR_SEEK:
- new_err_code = MAFW_RENDERER_ERROR_CANNOT_SET_POSITION;
- break;
- default:
- /* Unknown RESOURCE error */
- new_err_domain = MAFW_EXTENSION_ERROR;
- new_err_code = MAFW_EXTENSION_ERROR_FAILED;
- }
-
- } else if (error->domain == GST_STREAM_ERROR) {
- /* handle STREAM errors */
- switch (error->code) {
- case GST_STREAM_ERROR_TYPE_NOT_FOUND:
- new_err_code = MAFW_RENDERER_ERROR_TYPE_NOT_AVAILABLE;
- break;
- case GST_STREAM_ERROR_FORMAT:
- case GST_STREAM_ERROR_WRONG_TYPE:
- case GST_STREAM_ERROR_FAILED:
- new_err_code = MAFW_RENDERER_ERROR_UNSUPPORTED_TYPE;
- break;
- case GST_STREAM_ERROR_DECODE:
- case GST_STREAM_ERROR_DEMUX:
- new_err_code = MAFW_RENDERER_ERROR_CORRUPTED_FILE;
- break;
- case GST_STREAM_ERROR_CODEC_NOT_FOUND:
- new_err_code = MAFW_RENDERER_ERROR_CODEC_NOT_FOUND;
- break;
- case GST_STREAM_ERROR_DECRYPT:
- case GST_STREAM_ERROR_DECRYPT_NOKEY:
- new_err_code = MAFW_RENDERER_ERROR_DRM;
- break;
- default:
- /* Unknown STREAM error */
- new_err_domain = MAFW_EXTENSION_ERROR;
- new_err_code = MAFW_EXTENSION_ERROR_FAILED;
- }
- } else if (error->domain == MAFW_GST_RENDERER_ERROR) {
- /* Handle own errors. Errors that belong to this domain:
- - MAFW_GST_RENDERER_ERROR_PLUGIN_NOT_FOUND,
- - MAFW_GST_RENDERER_ERROR_VIDEO_CODEC_NOT_SUPPORTED,
- - MAFW_GST_RENDERER_ERROR_AUDIO_CODEC_NOT_SUPPORTED */
- new_err_code = MAFW_RENDERER_ERROR_UNSUPPORTED_TYPE;
- } else if (error->domain == MAFW_RENDERER_ERROR) {
- /* Worker may have sent MAFW_RENDERER_ERROR as well.
- No processing needed */
- new_err_code = error->code;
- } else {
- /* default */
- /* Unknown error */
- new_err_domain = MAFW_EXTENSION_ERROR;
- new_err_code = MAFW_EXTENSION_ERROR_FAILED;
- }
-
- g_set_error(&new_err, new_err_domain, new_err_code, "%s", error->message);
-
- _run_error_policy(self, new_err, &raise_error);
- g_error_free(new_err);
-
- if (raise_error) {
- g_signal_emit_by_name(MAFW_EXTENSION (self), "error",
- raise_error->domain,
- raise_error->code,
- raise_error->message);
- g_error_free(raise_error);
- }
-}
-
-static void _notify_eos(MafwGstRendererWorker *worker, gpointer owner)
-{
- MafwGstRenderer *renderer = (MafwGstRenderer*) owner;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER (renderer));
-
- g_return_if_fail((renderer->states != 0) &&
- (renderer->current_state != _LastMafwPlayState) &&
- (renderer->states[renderer->current_state] != NULL));
-
- mafw_gst_renderer_state_notify_eos(renderer->states[renderer->current_state],
- &error);
-
- if (error != NULL) {
- g_signal_emit_by_name(MAFW_EXTENSION(renderer), "error",
- error->domain, error->code,
- error->message);
- g_error_free(error);
- }
-}
-
-/*----------------------------------------------------------------------------
- Status
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_get_status(MafwRenderer *self, MafwRendererStatusCB callback,
- gpointer user_data)
-{
- MafwGstRenderer* renderer;
- gint index;
- MafwGstRendererPlaybackMode mode;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
- g_return_if_fail(callback != NULL);
- renderer = MAFW_GST_RENDERER(self);
-
- mode = mafw_gst_renderer_get_playback_mode(MAFW_GST_RENDERER(self));
- if ((mode == MAFW_GST_RENDERER_MODE_STANDALONE) || (renderer->iterator == NULL)) {
- index = -1;
- } else {
- index =
- mafw_playlist_iterator_get_current_index(renderer->iterator);
- }
-
- /* TODO: Set error parameter */
- callback(self, renderer->playlist, index, renderer->current_state,
- (const gchar*) renderer->media->object_id, user_data, NULL);
-}
-
-void mafw_gst_renderer_get_current_metadata(MafwRenderer *self,
- MafwRendererMetadataResultCB callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer;
- GHashTable *metadata;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
- renderer = MAFW_GST_RENDERER(self);
-
- metadata = mafw_gst_renderer_worker_get_current_metadata(
- renderer->worker);
-
- callback(self,
- (const gchar*) renderer->media->object_id,
- metadata,
- user_data,
- NULL);
-}
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-static void
-_playlist_contents_changed_handler(MafwPlaylist *playlist,
- guint from, guint nremove,
- guint nreplace,
- MafwGstRenderer *renderer)
-{
- /* Item(s) added to playlist, so new playable items could come */
- if (nreplace)
- renderer->play_failed_count = 0;
-}
-
-gboolean mafw_gst_renderer_assign_playlist(MafwRenderer *self,
- MafwPlaylist *playlist,
- GError **error)
-{
- MafwGstRenderer* renderer = (MafwGstRenderer*) self;
-
- g_return_val_if_fail(MAFW_IS_GST_RENDERER(self), FALSE);
-
- /* Get rid of previously assigned playlist */
- if (renderer->playlist != NULL) {
- g_signal_handlers_disconnect_matched(renderer->iterator,
- (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
- 0, 0, NULL,
- _playlist_changed_handler,
- NULL);
- g_signal_handlers_disconnect_matched(renderer->playlist,
- (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
- 0, 0, NULL,
- G_CALLBACK(_playlist_contents_changed_handler),
- NULL);
- /* Decrement the use count of the previous playlist because the
- renderer isn't going to use it more */
- mafw_playlist_decrement_use_count(renderer->playlist, NULL);
-
- g_object_unref(renderer->iterator);
- g_object_unref(renderer->playlist);
- }
-
- /* Assign the new playlist */
- if (playlist == NULL) {
- renderer->playlist = NULL;
- renderer->iterator = NULL;
- } else {
- GError *new_error = NULL;
- MafwPlaylistIterator *iterator = NULL;
-
- iterator = mafw_playlist_iterator_new();
- mafw_playlist_iterator_initialize(iterator, playlist,
- &new_error);
-
- g_object_ref(playlist);
-
- if (new_error == NULL) {
-
- renderer->playlist = playlist;
- renderer->iterator = iterator;
-
- /* Increment the use_count to avoid the playlist destruction
- while the playlist is assigned to some renderer */
- mafw_playlist_increment_use_count(renderer->playlist, NULL);
-
- g_signal_connect(iterator,
- "playlist-changed",
- G_CALLBACK(_playlist_changed_handler),
- renderer);
- g_signal_connect(renderer->playlist,
- "contents-changed",
- G_CALLBACK(_playlist_contents_changed_handler),
- renderer);
- }
- else {
- g_propagate_error (error, new_error);
- }
- }
-
- /* Set the new media and signal playlist changed signal */
- _signal_playlist_changed(renderer);
- mafw_gst_renderer_set_media_playlist(renderer);
-
-
- /* Stop playback */
- mafw_gst_renderer_stop(MAFW_RENDERER(renderer), NULL , NULL);
-
- return TRUE;
-}
-
-MafwGstRendererMovementResult mafw_gst_renderer_move(MafwGstRenderer *renderer,
- MafwGstRendererMovementType type,
- guint index,
- GError **error)
-{
- MafwGstRendererMovementResult value = MAFW_GST_RENDERER_MOVE_RESULT_OK;
-
- if (renderer->playlist == NULL) {
- value = MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST;
- } else {
- MafwPlaylistIteratorMovementResult result;
-
- switch (type) {
- case MAFW_GST_RENDERER_MOVE_TYPE_INDEX:
- result =
- mafw_playlist_iterator_move_to_index(renderer->iterator,
- index,
- error);
- break;
- case MAFW_GST_RENDERER_MOVE_TYPE_PREV:
- result =
- mafw_playlist_iterator_move_to_prev(renderer->iterator,
- error);
- break;
- case MAFW_GST_RENDERER_MOVE_TYPE_NEXT:
- result =
- mafw_playlist_iterator_move_to_next(renderer->iterator,
- error);
- break;
- }
-
- switch (result) {
- case MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK:
- value = MAFW_GST_RENDERER_MOVE_RESULT_OK;
- mafw_gst_renderer_set_media_playlist(renderer);
- break;
- case MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_INVALID:
- g_critical("Iterator is invalid!");
- value = MAFW_GST_RENDERER_MOVE_RESULT_ERROR;
- break;
- case MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR:
- value = MAFW_GST_RENDERER_MOVE_RESULT_ERROR;
- break;
- case MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_LIMIT:
- value = MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT;
- break;
- }
- }
-
- return value;
-}
-
-/*----------------------------------------------------------------------------
- Properties
- ----------------------------------------------------------------------------*/
-
-static void _set_error_policy(MafwGstRenderer *renderer, MafwRendererErrorPolicy policy)
-{
- renderer->error_policy = policy;
-}
-
-static MafwRendererErrorPolicy _get_error_policy(MafwGstRenderer *renderer)
-{
- return renderer->error_policy;
-}
-
-static void mafw_gst_renderer_get_property(MafwExtension *self,
- const gchar *key,
- MafwExtensionPropertyCallback callback,
- gpointer user_data)
-{
- MafwGstRenderer *renderer;
- GValue *value = NULL;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
- g_return_if_fail(callback != NULL);
- g_return_if_fail(key != NULL);
-
- renderer = MAFW_GST_RENDERER(self);
- if (!strcmp(key, MAFW_PROPERTY_RENDERER_VOLUME)) {
- guint volume;
-
- volume = mafw_gst_renderer_worker_get_volume(
- renderer->worker);
-
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_UINT);
- g_value_set_uint(value, volume);
- }
- else if (!strcmp(key, MAFW_PROPERTY_RENDERER_MUTE)) {
- gboolean mute;
- mute = mafw_gst_renderer_worker_get_mute(renderer->worker);
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_BOOLEAN);
- g_value_set_boolean(value, mute);
- }
- else if (!strcmp (key, MAFW_PROPERTY_RENDERER_XID)) {
- guint xid;
- xid = mafw_gst_renderer_worker_get_xid(renderer->worker);
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_UINT);
- g_value_set_uint(value, xid);
- }
- else if (!strcmp(key, MAFW_PROPERTY_RENDERER_ERROR_POLICY)) {
- guint policy;
- policy = _get_error_policy(renderer);
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_UINT);
- g_value_set_uint(value, policy);
- }
- else if (!strcmp(key, MAFW_PROPERTY_RENDERER_AUTOPAINT)) {
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_BOOLEAN);
- g_value_set_boolean(
- value,
- mafw_gst_renderer_worker_get_autopaint(
- renderer->worker));
- } else if (!strcmp(key, MAFW_PROPERTY_RENDERER_COLORKEY)) {
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_INT);
- g_value_set_int(
- value,
- mafw_gst_renderer_worker_get_colorkey(
- renderer->worker));
- }
-#ifdef HAVE_GDKPIXBUF
- else if (!strcmp(key,
- MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE)) {
- gboolean current_frame_on_pause;
- current_frame_on_pause =
- mafw_gst_renderer_worker_get_current_frame_on_pause(renderer->worker);
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_BOOLEAN);
- g_value_set_boolean(value, current_frame_on_pause);
- }
-#endif
- else if (!strcmp(key,
- MAFW_PROPERTY_GST_RENDERER_TV_CONNECTED)) {
- value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_BOOLEAN);
- g_value_set_boolean(value, renderer->tv_connected);
- }
- else if (!strcmp(key,
- MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS)){
- /* Delegate in the state. */
- value = mafw_gst_renderer_state_get_property_value(
- MAFW_GST_RENDERER_STATE(
- renderer->states[renderer->current_state]),
- MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS);
-
- if (!value) {
- /* Something goes wrong. */
- error = g_error_new(
- MAFW_GST_RENDERER_ERROR,
- MAFW_EXTENSION_ERROR_GET_PROPERTY,
- "Error while getting the property value");
- }
- }
- else {
- /* Unsupported property */
- error = g_error_new(MAFW_GST_RENDERER_ERROR,
- MAFW_EXTENSION_ERROR_GET_PROPERTY,
- "Unsupported property");
- }
-
- callback(self, key, value, user_data, error);
-}
-
-static void mafw_gst_renderer_set_property(MafwExtension *self,
- const gchar *key,
- const GValue *value)
-{
- MafwGstRenderer *renderer;
-
- g_return_if_fail(MAFW_IS_GST_RENDERER(self));
- g_return_if_fail(key != NULL);
-
- renderer = MAFW_GST_RENDERER(self);
-
- if (!strcmp(key, MAFW_PROPERTY_RENDERER_VOLUME)) {
- guint volume = g_value_get_uint(value);
- if (volume > 100)
- volume = 100;
- mafw_gst_renderer_worker_set_volume(renderer->worker,
- volume);
- /* Property-changed emision is done by worker */
- return;
- }
- else if (!strcmp(key, MAFW_PROPERTY_RENDERER_MUTE)) {
- gboolean mute = g_value_get_boolean(value);
- mafw_gst_renderer_worker_set_mute(renderer->worker, mute);
- }
- else if (!strcmp(key, MAFW_PROPERTY_RENDERER_XID)) {
- XID xid = g_value_get_uint(value);
- mafw_gst_renderer_worker_set_xid(renderer->worker, xid);
- }
- else if (!strcmp(key, MAFW_PROPERTY_RENDERER_ERROR_POLICY)) {
- MafwRendererErrorPolicy policy = g_value_get_uint(value);
- _set_error_policy(renderer, policy);
- }
- else if (!strcmp(key, MAFW_PROPERTY_RENDERER_AUTOPAINT)) {
- mafw_gst_renderer_worker_set_autopaint(
- renderer->worker,
- g_value_get_boolean(value));
- }
- else if (!strcmp(key, MAFW_PROPERTY_RENDERER_COLORKEY)) {
- mafw_gst_renderer_worker_set_colorkey(
- renderer->worker,
- g_value_get_int(value));
- }
-#ifdef HAVE_GDKPIXBUF
- else if (!strcmp(key,
- MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE)) {
- gboolean current_frame_on_pause = g_value_get_boolean(value);
- mafw_gst_renderer_worker_set_current_frame_on_pause(renderer->worker,
- current_frame_on_pause);
- }
-#endif
- else return;
-
- /* FIXME I'm not sure when to emit property-changed signals.
- * Maybe we should let the worker do it, when the change
- * reached the hardware... */
- mafw_extension_emit_property_changed(self, key, value);
-}
-
-/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef MAFW_GST_RENDERER_H
-#define MAFW_GST_RENDERER_H
-
-#include <glib-object.h>
-#include <libmafw/mafw-renderer.h>
-#include <libmafw/mafw-registry.h>
-#include <gst/gst.h>
-#include <gst/pbutils/pbutils.h>
-#include <libhal.h>
-#include <gconf/gconf-client.h>
-
-#include "mafw-gst-renderer-utils.h"
-#include "mafw-gst-renderer-worker.h"
-#include "mafw-playlist-iterator.h"
-/* Solving the cyclic dependencies */
-typedef struct _MafwGstRenderer MafwGstRenderer;
-typedef struct _MafwGstRendererClass MafwGstRendererClass;
-#include "mafw-gst-renderer-state.h"
-
-#ifdef HAVE_CONIC
-#include <conicconnection.h>
-#endif
-
-typedef enum {
- MAFW_GST_RENDERER_ERROR_PLUGIN_NOT_FOUND,
- MAFW_GST_RENDERER_ERROR_VIDEO_CODEC_NOT_SUPPORTED,
- MAFW_GST_RENDERER_ERROR_AUDIO_CODEC_NOT_SUPPORTED,
-} MafwGstRendererError;
-
-typedef enum {
- MAFW_GST_RENDERER_MODE_PLAYLIST,
- MAFW_GST_RENDERER_MODE_STANDALONE,
-} MafwGstRendererPlaybackMode;
-
-typedef enum {
- MAFW_GST_RENDERER_MOVE_RESULT_OK,
- MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST,
- MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT,
- MAFW_GST_RENDERER_MOVE_RESULT_ERROR,
-} MafwGstRendererMovementResult;
-
-typedef enum {
- MAFW_GST_RENDERER_MOVE_TYPE_INDEX,
- MAFW_GST_RENDERER_MOVE_TYPE_PREV,
- MAFW_GST_RENDERER_MOVE_TYPE_NEXT,
-} MafwGstRendererMovementType;
-
-#ifdef HAVE_GDKPIXBUF
-#define MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE \
- "current-frame-on-pause"
-#endif
-
-#define MAFW_PROPERTY_GST_RENDERER_TV_CONNECTED "tv-connected"
-
-/*----------------------------------------------------------------------------
- GObject type conversion macros
- ----------------------------------------------------------------------------*/
-
-#define MAFW_TYPE_GST_RENDERER \
- (mafw_gst_renderer_get_type())
-#define MAFW_GST_RENDERER(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_GST_RENDERER, MafwGstRenderer))
-#define MAFW_IS_GST_RENDERER(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_GST_RENDERER))
-#define MAFW_GST_RENDERER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_GST_RENDERER, MafwGstRenderer))
-#define MAFW_GST_RENDERER_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_GST_RENDERER, \
- MafwGstRendererClass))
-#define MAFW_IS_GST_RENDERER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_GST_RENDERER))
-
-#define MAFW_GST_RENDERER_ERROR (mafw_gst_renderer_error_quark ())
-
-/* Gst renderer plugin name for the plugin descriptor */
-#define MAFW_GST_RENDERER_PLUGIN_NAME "Mafw-Gst-Renderer-Plugin"
-/* Gst renderer name */
-#define MAFW_GST_RENDERER_NAME "Mafw-Gst-Renderer"
-/* Gst renderer UUID */
-#define MAFW_GST_RENDERER_UUID "gstrenderer"
-
-/*----------------------------------------------------------------------------
- Type definitions
- ----------------------------------------------------------------------------*/
-
-typedef struct {
- gchar *object_id;
- gchar *uri;
- gchar *title;
- gchar *artist;
- gchar *album;
-
- gint duration;
- gint position;
-
- /* Seekability coming from source */
- SeekabilityType seekability;
-} MafwGstRendererMedia;
-
-struct _MafwGstRendererClass {
- MafwRendererClass parent;
-};
-
-/*
- * media: Current media details
- * worker: Worker
- * registry: The registry that owns this renderer
- * media_timer: Stream timer data
- * current_state: The renderer's current state
- * playlist: The renderer's playlist
- * play_index: A playlist index that is currently playing
- * seek_pending: Seek is pending or ongoing
- * seek_type_pending: Type of the pending seek
- * seeking_to: The position of pending seek (milliseconds)
- * is_stream: is the URI a stream?
- * play_failed_count: The number of unably played items from the playlist.
- * playback_mode: Playback mode
- * resume_playlist: Do we want to resume playlist playback when play_object
- * is finished
- * states: State array
- * error_policy: error policy
- * tv_connected: if TV-out cable is connected
- */
-struct _MafwGstRenderer{
- MafwRenderer parent;
-
- MafwGstRendererMedia *media;
- MafwGstRendererWorker *worker;
- MafwRegistry *registry;
- LibHalContext *hal_ctx;
- MafwPlayState current_state;
- MafwPlaylist *playlist;
- MafwPlaylistIterator *iterator;
- gboolean seek_pending;
- GstSeekType seek_type_pending;
- gint seeking_to;
- gboolean is_stream;
- gint update_playcount_id;
- guint play_failed_count;
-
- MafwGstRendererPlaybackMode playback_mode;
- gboolean resume_playlist;
- MafwGstRendererState **states;
- MafwRendererErrorPolicy error_policy;
- gboolean tv_connected;
-
-#ifdef HAVE_CONIC
- gboolean connected;
- ConIcConnection *connection;
-#endif
- GConfClient *gconf_client;
-};
-
-typedef struct {
- MafwGstRenderer *renderer;
- GError *error;
-} MafwGstRendererErrorClosure;
-
-G_BEGIN_DECLS
-
-GType mafw_gst_renderer_get_type(void);
-GObject *mafw_gst_renderer_new(MafwRegistry *registry);
-GQuark mafw_gst_renderer_error_quark(void);
-
-/*----------------------------------------------------------------------------
- Playback
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_play(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data);
-void mafw_gst_renderer_play_object(MafwRenderer *self, const gchar *object_id,
- MafwRendererPlaybackCB callback,
- gpointer user_data);
-void mafw_gst_renderer_stop(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data);
-void mafw_gst_renderer_pause(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data);
-void mafw_gst_renderer_resume(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data);
-
-/*----------------------------------------------------------------------------
- Status
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_get_status(MafwRenderer *self, MafwRendererStatusCB callback,
- gpointer user_data);
-
-/*----------------------------------------------------------------------------
- Set Media
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_set_object(MafwGstRenderer *self, const gchar *object_id);
-void mafw_gst_renderer_clear_media(MafwGstRenderer *self);
-
-/*----------------------------------------------------------------------------
- Metadata
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_get_metadata(MafwGstRenderer* self, const gchar* objectid,
- GError **error);
-gboolean mafw_gst_renderer_update_stats(gpointer data);
-
-/*----------------------------------------------------------------------------
- Playlist
- ----------------------------------------------------------------------------*/
-
-gboolean mafw_gst_renderer_assign_playlist(MafwRenderer *self,
- MafwPlaylist *playlist,
- GError **error);
-void mafw_gst_renderer_next(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data);
-void mafw_gst_renderer_previous(MafwRenderer *self, MafwRendererPlaybackCB callback,
- gpointer user_data);
-void mafw_gst_renderer_goto_index(MafwRenderer *self, guint index,
- MafwRendererPlaybackCB callback,
- gpointer user_data);
-MafwGstRendererMovementResult mafw_gst_renderer_move(MafwGstRenderer *renderer,
- MafwGstRendererMovementType type,
- guint index,
- GError **error);
-
-/*----------------------------------------------------------------------------
- Set media
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_set_media_playlist(MafwGstRenderer* self);
-
-/*----------------------------------------------------------------------------
- Position
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_set_position(MafwRenderer *self,
- MafwRendererSeekMode mode, gint seconds,
- MafwRendererPositionCB callback,
- gpointer user_data);
-void mafw_gst_renderer_get_position(MafwRenderer *self, MafwRendererPositionCB callback,
- gpointer user_data);
-
-/*----------------------------------------------------------------------------
- Metadata
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_get_current_metadata(MafwRenderer *self,
- MafwRendererMetadataResultCB callback,
- gpointer user_data);
-
-/*----------------------------------------------------------------------------
- Local API
- ----------------------------------------------------------------------------*/
-
-void mafw_gst_renderer_set_state(MafwGstRenderer *self, MafwPlayState state);
-
-gboolean mafw_gst_renderer_manage_error_idle(gpointer data);
-
-void mafw_gst_renderer_manage_error(MafwGstRenderer *self, const GError *error);
-
-void mafw_gst_renderer_set_playback_mode(MafwGstRenderer *self,
- MafwGstRendererPlaybackMode mode);
-
-MafwGstRendererPlaybackMode mafw_gst_renderer_get_playback_mode(
- MafwGstRenderer *self);
-
-void mafw_gst_renderer_update_source_duration(MafwGstRenderer *renderer,
- gint duration);
-
-G_END_DECLS
-
-#endif
-
-/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "mafw-playlist-iterator.h"
-#include "mafw-gst-renderer-marshal.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-playlist-iterator"
-
-struct _MafwPlaylistIteratorPrivate {
- MafwPlaylist *playlist;
- gint current_index;
- gchar *current_objectid;
- gint size;
-};
-
-typedef gboolean (*movement_function) (MafwPlaylist *playlist,
- guint *index,
- gchar **objectid,
- GError **error);
-
-enum {
- PLAYLIST_CHANGED = 0,
- LAST_SIGNAL,
-};
-
-static guint mafw_playlist_iterator_signals[LAST_SIGNAL];
-
-G_DEFINE_TYPE(MafwPlaylistIterator, mafw_playlist_iterator, G_TYPE_OBJECT);
-
-static void
-mafw_playlist_iterator_dispose(GObject *object)
-{
- MafwPlaylistIterator *iterator = (MafwPlaylistIterator *) object;
-
- g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
-
- mafw_playlist_iterator_invalidate(iterator);
-
- G_OBJECT_CLASS(mafw_playlist_iterator_parent_class)->dispose(object);
-}
-
-static void
-mafw_playlist_iterator_class_init(MafwPlaylistIteratorClass *klass)
-{
- GObjectClass *gclass = NULL;
-
- gclass = G_OBJECT_CLASS(klass);
- g_return_if_fail(gclass != NULL);
-
- g_type_class_add_private(klass, sizeof(MafwPlaylistIteratorPrivate));
-
- gclass->dispose = mafw_playlist_iterator_dispose;
-
- mafw_playlist_iterator_signals[PLAYLIST_CHANGED] =
- g_signal_new("playlist-changed",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(MafwPlaylistIteratorClass, playlist_changed),
- NULL,
- NULL,
- mafw_gst_renderer_marshal_VOID__BOOLEAN_UINT_INT_STRING,
- G_TYPE_NONE,
- 4,
- G_TYPE_BOOLEAN,
- G_TYPE_UINT, G_TYPE_INT, G_TYPE_STRING);
-}
-
-static void
-mafw_playlist_iterator_init(MafwPlaylistIterator *self)
-{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
- MAFW_TYPE_PLAYLIST_ITERATOR,
- MafwPlaylistIteratorPrivate);
-}
-
-static void
-mafw_playlist_iterator_set_data(MafwPlaylistIterator *iterator, gint index,
- gchar *objectid)
-{
- g_assert(mafw_playlist_iterator_is_valid(iterator));
-
- g_free(iterator->priv->current_objectid);
- iterator->priv->current_index = index;
- iterator->priv->current_objectid = objectid;
-}
-
-static MafwPlaylistIteratorMovementResult
-mafw_playlist_iterator_move_to_next_in_direction(MafwPlaylistIterator *iterator,
- movement_function get_next_in_direction,
- GError **error)
-{
- gint index;
- gchar *objectid = NULL;
- GError *new_error = NULL;
- gboolean playlist_movement_result = FALSE;
- MafwPlaylistIteratorMovementResult iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK;
-
- g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator),
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_INVALID);
-
- index = iterator->priv->current_index;
-
- playlist_movement_result =
- get_next_in_direction (iterator->priv->playlist,
- (guint *) &index,
- &objectid, &new_error);
-
- if (new_error != NULL) {
- g_propagate_error(error, new_error);
- iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR;
- } else if (playlist_movement_result) {
- mafw_playlist_iterator_set_data(iterator, index, objectid);
- } else {
- iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_LIMIT;
- }
-
- return iterator_movement_result;
-}
-
-static void
-mafw_playlist_iterator_playlist_contents_changed_handler(MafwPlaylist *playlist,
- guint from,
- guint nremove,
- guint nreplace,
- gpointer user_data)
-{
- gint play_index;
- gboolean clip_changed = FALSE;
- GError *error = NULL;
- MafwPlaylistIterator *iterator = (MafwPlaylistIterator*) user_data;
-
- g_return_if_fail(MAFW_IS_PLAYLIST(playlist));
- g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
-
- if (iterator->priv->playlist == NULL) {
- g_critical("Got playlist:contents-changed but renderer has no" \
- "playlist assigned!. Skipping...");
- return;
- }
-
- play_index = iterator->priv->current_index;
- iterator->priv->size += nreplace;
-
- if (nremove > 0) {
- /* Items have been removed from the playlist */
- iterator->priv->size -= nremove;
- if ((play_index >= from) &&
- (play_index < from + nremove)) {
- /* The current index has been removed */
- guint pls_size =
- mafw_playlist_iterator_get_size(iterator,
- &error);
- if (error == NULL) {
- /* Is the current index invalid now? If not,
- set current item to the last in the playlist,
- otherwise the keep the index and update the
- media */
- if (pls_size == 0) {
- mafw_playlist_iterator_set_data(iterator, -1, NULL);
- } else if (play_index >= pls_size) {
- mafw_playlist_iterator_move_to_index(iterator,
- pls_size - 1,
- &error);
- } else {
- mafw_playlist_iterator_update(iterator,
- &error);
- }
-
- clip_changed = TRUE;
- }
- } else if (from < play_index) {
- /* The current index has been moved towards
- the head of the playlist */
- play_index -= nremove;
- if (play_index < 0) {
- play_index = 0;
- }
- mafw_playlist_iterator_move_to_index(iterator,
- play_index,
- &error);
- }
- } else if (nremove == 0) {
- /* Items have been inserted in the playlist */
- if (play_index == -1) {
- /* First item has been added to an empty playlist */
- mafw_playlist_iterator_reset(iterator,
- &error);
- clip_changed = TRUE;
- } else if (play_index >= from) {
- /* The current item has been moved towards the
- tail of the playlist */
- mafw_playlist_iterator_move_to_index(iterator,
- play_index + nreplace,
- &error);
- }
- }
-
- if (error != NULL) {
- g_critical("playlist::contents-changed handler failed "
- "with \"%s\"", error->message);
- g_signal_emit(iterator,
- mafw_playlist_iterator_signals[PLAYLIST_CHANGED],
- 0, FALSE, error->domain, error->code, error->message);
- g_error_free (error);
- } else {
- g_signal_emit(iterator,
- mafw_playlist_iterator_signals[PLAYLIST_CHANGED],
- 0, clip_changed, 0, 0, NULL);
- }
-}
-
-static void
-mafw_playlist_iterator_playlist_item_moved_handler(MafwPlaylist *playlist,
- guint from,
- guint to,
- gpointer user_data)
-{
- MafwPlaylistIterator *iterator = (MafwPlaylistIterator *) user_data;
- gint play_index;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_PLAYLIST(playlist));
- g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
-
- if (iterator->priv->playlist == NULL) {
- g_critical("Got playlist:item-moved but renderer has not a " \
- "playlist assigned! Skipping...");
- return;
- }
-
- play_index = iterator->priv->current_index;
-
- if (play_index == from) {
- /* So the current item has been moved, let's update the
- the current index to the new location */
- mafw_playlist_iterator_move_to_index(iterator, to, &error);
- } else if (play_index > from && play_index <= to) {
- /* So we current item has been pushed one position towards
- the head, let's update the current index */
- mafw_playlist_iterator_move_to_prev(iterator, &error);
- } else if (play_index >= to && play_index < from) {
- /* So we current item has been pushed one position towards
- the head, let's update the current index */
- mafw_playlist_iterator_move_to_next(iterator, &error);
- }
-
- if (error != NULL) {
- g_critical("playlist::item-moved handler failed "
- "with \"%s\"", error->message);
- g_error_free (error);
- }
-}
-
-MafwPlaylistIterator *
-mafw_playlist_iterator_new(void)
-{
- MafwPlaylistIterator *iterator = (MafwPlaylistIterator *)
- g_object_new(MAFW_TYPE_PLAYLIST_ITERATOR, NULL);
-
- g_assert(iterator != NULL);
-
- iterator->priv->playlist = NULL;
- iterator->priv->current_index = -1;
- iterator->priv->current_objectid = NULL;
- iterator->priv->size = -1;
-
- return iterator;
-}
-
-void
-mafw_playlist_iterator_initialize(MafwPlaylistIterator *iterator,
- MafwPlaylist *playlist, GError **error)
-{
- guint size;
- gint index = -1;
- gchar *objectid = NULL;
- GError *new_error = NULL;
-
- g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
- g_return_if_fail(iterator->priv->playlist == NULL);
-
- iterator->priv->size = -1;
-
- mafw_playlist_get_starting_index(playlist, (guint *) &index, &objectid,
- &new_error);
-
- if (new_error == NULL) {
- size = mafw_playlist_get_size(playlist, &new_error);
- }
-
- if (new_error == NULL) {
- iterator->priv->playlist = g_object_ref(playlist);
- iterator->priv->current_index = index;
- iterator->priv->current_objectid = objectid;
- iterator->priv->size = size;
-
- g_signal_connect(playlist,
- "item-moved",
- G_CALLBACK(mafw_playlist_iterator_playlist_item_moved_handler),
- iterator);
- g_signal_connect(playlist,
- "contents-changed",
- G_CALLBACK(mafw_playlist_iterator_playlist_contents_changed_handler),
- iterator);
- }
- else {
- g_propagate_error (error, new_error);
- }
-}
-
-void
-mafw_playlist_iterator_invalidate(MafwPlaylistIterator *iterator)
-{
- g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
-
- if (iterator->priv->playlist != NULL) {
- g_signal_handlers_disconnect_matched(iterator->priv->playlist,
- (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
- 0, 0, NULL,
- mafw_playlist_iterator_playlist_item_moved_handler,
- NULL);
-
- g_signal_handlers_disconnect_matched(iterator->priv->playlist,
- (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
- 0, 0, NULL,
- mafw_playlist_iterator_playlist_contents_changed_handler,
- NULL);
-
- g_object_unref(iterator->priv->playlist);
- g_free(iterator->priv->current_objectid);
- iterator->priv->playlist = NULL;
- iterator->priv->current_index = -1;
- iterator->priv->current_objectid = NULL;
- iterator->priv->size = -1;
- }
-}
-
-gboolean
-mafw_playlist_iterator_is_valid(MafwPlaylistIterator *iterator)
-{
- g_return_val_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator), FALSE);
-
- return iterator->priv->playlist != NULL;
-}
-
-void
-mafw_playlist_iterator_reset(MafwPlaylistIterator *iterator, GError **error)
-{
- gint index = -1;
- gchar *objectid = NULL;
- GError *new_error = NULL;
-
- g_return_if_fail(mafw_playlist_iterator_is_valid(iterator));
-
- mafw_playlist_get_starting_index(iterator->priv->playlist,
- (guint *) &index,
- &objectid, &new_error);
-
- if (new_error == NULL) {
- mafw_playlist_iterator_set_data(iterator, index, objectid);
- }
- else {
- g_propagate_error (error, new_error);
- }
-}
-
-void
-mafw_playlist_iterator_move_to_last(MafwPlaylistIterator *iterator,
- GError **error)
-{
- GError *new_error = NULL;
- gint index = -1;
- gchar *objectid = NULL;
-
- g_return_if_fail(mafw_playlist_iterator_is_valid(iterator));
-
- mafw_playlist_get_last_index(iterator->priv->playlist,
- (guint *) &index,
- &objectid, &new_error);
-
- if (new_error == NULL) {
- mafw_playlist_iterator_set_data(iterator, index, objectid);
- }
- else {
- g_propagate_error (error, new_error);
- }
-}
-
-MafwPlaylistIteratorMovementResult
-mafw_playlist_iterator_move_to_next(MafwPlaylistIterator *iterator,
- GError **error)
-{
- return mafw_playlist_iterator_move_to_next_in_direction(iterator,
- mafw_playlist_get_next,
- error);
-}
-
-MafwPlaylistIteratorMovementResult
-mafw_playlist_iterator_move_to_prev(MafwPlaylistIterator *iterator,
- GError **error)
-{
- return mafw_playlist_iterator_move_to_next_in_direction(iterator,
- mafw_playlist_get_prev,
- error);
-}
-
-MafwPlaylistIteratorMovementResult
-mafw_playlist_iterator_move_to_index(MafwPlaylistIterator *iterator,
- gint index,
- GError **error)
-{
- GError *new_error = NULL;
- MafwPlaylistIteratorMovementResult iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK;
- gint playlist_size;
-
- g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator),
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_INVALID);
-
- playlist_size = mafw_playlist_iterator_get_size(iterator, &new_error);
-
- if (new_error != NULL) {
- g_propagate_error(error, new_error);
- iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR;
- } else if ((index < 0) || (index >= playlist_size)) {
- iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_LIMIT;
- } else {
- gchar *objectid =
- mafw_playlist_get_item(iterator->priv->playlist,
- index,
- &new_error);
-
- if (new_error != NULL) {
- g_propagate_error(error, new_error);
- iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR;
- } else {
- mafw_playlist_iterator_set_data(iterator, index, objectid);
- }
- }
-
- return iterator_movement_result;
-}
-
-void
-mafw_playlist_iterator_update(MafwPlaylistIterator *iterator, GError **error)
-{
- GError *new_error = NULL;
- gchar *objectid = NULL;
-
- objectid =
- mafw_playlist_get_item(iterator->priv->playlist,
- iterator->priv->current_index,
- &new_error);
-
- if (new_error != NULL) {
- g_propagate_error(error, new_error);
- } else {
- mafw_playlist_iterator_set_data(iterator,
- iterator->priv->current_index,
- objectid);
- }
-}
-
-const gchar *
-mafw_playlist_iterator_get_current_objectid(MafwPlaylistIterator *iterator)
-{
- g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator), NULL);
-
- return iterator->priv->current_objectid;
-}
-
-gint
-mafw_playlist_iterator_get_current_index(MafwPlaylistIterator *iterator)
-{
- g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator), 0);
-
- return iterator->priv->current_index;
-}
-
-gint
-mafw_playlist_iterator_get_size(MafwPlaylistIterator *iterator,
- GError **error)
-{
- g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator), -1);
-
- if (iterator->priv->size == -1) {
- iterator->priv->size =
- mafw_playlist_get_size(iterator->priv->playlist,
- error);
- }
-
- return iterator->priv->size;
-}
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef MAFW_PLAYLIST_ITERATOR_H
-#define MAFW_PLAYLIST_ITERATOR_H
-
-#include <glib-object.h>
-#include <libmafw/mafw.h>
-
-G_BEGIN_DECLS
-
-typedef struct _MafwPlaylistIteratorPrivate MafwPlaylistIteratorPrivate;
-
-typedef struct {
- GObject g_object;
-
- MafwPlaylistIteratorPrivate *priv;
-} MafwPlaylistIterator;
-
-typedef struct {
- GObjectClass g_object_class;
-
- /* Signals */
- void (*playlist_changed)(MafwPlaylistIterator *iterator,
- gboolean current_item_changed,
- GQuark domain, gint code, const gchar *message);
-} MafwPlaylistIteratorClass;
-
-typedef enum {
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK,
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_LIMIT,
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_INVALID,
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR,
-} MafwPlaylistIteratorMovementResult;
-
-#define MAFW_TYPE_PLAYLIST_ITERATOR \
- (mafw_playlist_iterator_get_type())
-#define MAFW_PLAYLIST_ITERATOR(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_PLAYLIST_ITERATOR, MafwPlaylistIterator))
-#define MAFW_IS_PLAYLIST_ITERATOR(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_PLAYLIST_ITERATOR))
-#define MAFW_PLAYLIST_ITERATOR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_PLAYLIST_ITERATOR, MafwPlaylistIterator))
-#define MAFW_PLAYLIST_ITERATOR_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_PLAYLIST_ITERATOR, \
- MafwPlaylistIteratorClass))
-#define MAFW_IS_PLAYLIST_ITERATOR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_PLAYLIST_ITERATOR))
-
-G_END_DECLS
-
-GType mafw_playlist_iterator_get_type(void);
-MafwPlaylistIterator *mafw_playlist_iterator_new(void);
-void mafw_playlist_iterator_initialize(MafwPlaylistIterator *iterator,
- MafwPlaylist *playlist,
- GError **error);
-void mafw_playlist_iterator_invalidate(MafwPlaylistIterator *iterator);
-gboolean mafw_playlist_iterator_is_valid(MafwPlaylistIterator *iterator);
-void mafw_playlist_iterator_reset(MafwPlaylistIterator *iterator, GError **error);
-void mafw_playlist_iterator_move_to_last(MafwPlaylistIterator *iterator, GError **error);
-MafwPlaylistIteratorMovementResult mafw_playlist_iterator_move_to_next(MafwPlaylistIterator *iterator,
- GError **error);
-MafwPlaylistIteratorMovementResult mafw_playlist_iterator_move_to_prev(MafwPlaylistIterator *iterator,
- GError **error);
-MafwPlaylistIteratorMovementResult mafw_playlist_iterator_move_to_index(MafwPlaylistIterator *iterator,
- gint index,
- GError **error);
-void mafw_playlist_iterator_update(MafwPlaylistIterator *iterator, GError **error);
-const gchar *mafw_playlist_iterator_get_current_objectid(MafwPlaylistIterator *iterator);
-gint mafw_playlist_iterator_get_current_index(MafwPlaylistIterator *iterator);
-gint mafw_playlist_iterator_get_size(MafwPlaylistIterator *iterator,
- GError **error);
-
-#endif
+++ /dev/null
-prefix=
-exec_prefix=
-libdir=${pcfiledir}/libmafw-gst-renderer
-includedir=${pcfiledir}/
-
-Name: mafw-gst-renderer
-Description: MAFW local renderer
-Version: @VERSION@
-Libs: ${libdir}/mafw-gst-renderer.la
-Cflags: -I${includedir}
-Requires: gobject-2.0 gstreamer-0.10 mafw
--- /dev/null
+Visa Smolander <visa.smolander@nokia.com>
+Zeeshan Ali <zeeshan.ali@nokia.com>
+Mikael Saarenpää <mikael.saarenpaa@nokia.com>
+Antía Puentes Felpeto <apuentes@igalia.com>
+Iago Toral Quiroga <itoral@igalia.com>
+Juan Suárez Romero <jasuarez@igalia.com>
+Sandor Pinter <sandor.pinter@blumsoft.eu>
+Xabier Rodríguez Calvar <xrcalvar@igalia.com>
+Juha Kellokoski <veitikka6@gmail.com>
+Mika Tapojarvi <mika.tapojarvi@sse.fi>
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null
+#
+# Makefile.am for MAFW gst renderer library.
+#
+# Author: Visa Smolander <visa.smolander@nokia.com>
+#
+# Copyright (C) 2007, 2008, 2009 Nokia. All rights reserved.
+
+
+SUBDIRS = libmafw-gst-renderer applet po
+
+if ENABLE_TESTS
+SUBDIRS += tests
+endif
+
+noinst_DATA = mafw-gst-renderer-uninstalled.pc
+EXTRA_DIST = mafw-gst-renderer-uninstalled.pc.in
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = aclocal.m4 compile config.guess \
+ config.sub configure depcomp \
+ install-sh ltmain.sh Makefile.in \
+ missing config.h.in *-stamp omf.make
+
+if ENABLE_COVERAGE
+LCOV_DATA_DIR = lcov-data
+LCOV_DATA_FILE = lcov.info
+
+distclean-local:
+ -rm -rf $(LCOV_DATA_DIR)
+
+lcov-zero-counters:
+ $(LCOV) -z -d .
+
+lcov:
+ -mkdir -p $(LCOV_DATA_DIR)
+ $(LCOV) -c -d . -o $(LCOV_DATA_DIR)/$(LCOV_DATA_FILE)
+ genhtml -s $(LCOV_DATA_DIR)/$(LCOV_DATA_FILE) -o $(LCOV_DATA_DIR)
+ @echo
+ @echo "Please, have a look on ./$(LCOV_DATA_DIR)/index.html for coverage statistics"
+ @echo
+endif
--- /dev/null
+dnl AM_PATH_CHECK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for check, and define CHECK_CFLAGS and CHECK_LIBS
+dnl
+
+AC_DEFUN([AM_PATH_CHECK],
+[
+ AC_ARG_WITH(check,
+ [ --with-check=PATH prefix where check is installed [default=auto]])
+
+ min_check_version=ifelse([$1], ,0.8.2,$1)
+
+ AC_MSG_CHECKING(for check - version >= $min_check_version)
+
+ if test x$with_check = xno; then
+ AC_MSG_RESULT(disabled)
+ ifelse([$3], , AC_MSG_ERROR([disabling check is not supported]), [$3])
+ else
+ if test "x$with_check" != x; then
+ CHECK_CFLAGS="-I$with_check/include"
+ CHECK_LIBS="-L$with_check/lib -lcheck"
+ else
+ CHECK_CFLAGS=""
+ CHECK_LIBS="-lcheck"
+ fi
+
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_LIBS="$LIBS"
+
+ CFLAGS="$CFLAGS $CHECK_CFLAGS"
+ LIBS="$CHECK_LIBS $LIBS"
+
+ rm -f conf.check-test
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <check.h>
+
+int main ()
+{
+ int major, minor, micro;
+ char *tmp_version;
+
+ system ("touch conf.check-test");
+
+ /* HP/UX 9 (%@#!) writes to sscanf strings */
+ tmp_version = strdup("$min_check_version");
+ if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
+ printf("%s, bad version string\n", "$min_check_version");
+ return 1;
+ }
+
+ if ((CHECK_MAJOR_VERSION != check_major_version) ||
+ (CHECK_MINOR_VERSION != check_minor_version) ||
+ (CHECK_MICRO_VERSION != check_micro_version))
+ {
+ printf("\n*** The check header file (version %d.%d.%d) does not match\n",
+ CHECK_MAJOR_VERSION, CHECK_MINOR_VERSION, CHECK_MICRO_VERSION);
+ printf("*** the check library (version %d.%d.%d).\n",
+ check_major_version, check_minor_version, check_micro_version);
+ return 1;
+ }
+
+ if ((check_major_version > major) ||
+ ((check_major_version == major) && (check_minor_version > minor)) ||
+ ((check_major_version == major) && (check_minor_version == minor) && (check_micro_version >= micro)))
+ {
+ return 0;
+ }
+ else
+ {
+ printf("\n*** An old version of check (%d.%d.%d) was found.\n",
+ check_major_version, check_minor_version, check_micro_version);
+ printf("*** You need a version of check being at least %d.%d.%d.\n", major, minor, micro);
+ printf("***\n");
+ printf("*** If you have already installed a sufficiently new version, this error\n");
+ printf("*** probably means that the wrong copy of the check library and header\n");
+ printf("*** file is being found. Rerun configure with the --with-check=PATH option\n");
+ printf("*** to specify the prefix where the correct version was installed.\n");
+ }
+
+ return 1;
+}
+],, no_check=yes, [echo $ac_n "cross compiling; assumed OK... $ac_c"])
+
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+
+ if test "x$no_check" = x ; then
+ AC_MSG_RESULT(yes)
+ ifelse([$2], , :, [$2])
+ else
+ AC_MSG_RESULT(no)
+ if test -f conf.check-test ; then
+ :
+ else
+ echo "*** Could not run check test program, checking why..."
+ CFLAGS="$CFLAGS $CHECK_CFLAGS"
+ LIBS="$CHECK_LIBS $LIBS"
+ AC_TRY_LINK([
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <check.h>
+], , [ echo "*** The test program compiled, but did not run. This usually means"
+ echo "*** that the run-time linker is not finding check. You'll need to set your"
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+ echo "*** to the installed location Also, make sure you have run ldconfig if that"
+ echo "*** is required on your system"
+ echo "***"
+ echo "*** If you have an old version installed, it is best to remove it, although"
+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
+ [ echo "*** The test program failed to compile or link. See the file config.log for"
+ echo "*** the exact error that occured." ])
+
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+
+ CHECK_CFLAGS=""
+ CHECK_LIBS=""
+
+ rm -f conf.check-test
+ ifelse([$3], , AC_MSG_ERROR([check not found]), [$3])
+ fi
+
+ AC_SUBST(CHECK_CFLAGS)
+ AC_SUBST(CHECK_LIBS)
+
+ rm -f conf.check-test
+
+ fi
+])
+
+dnl AM_MAFW_PLUGIN_CHECK(PLUGIN, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl Test to check whether a plugin exists
+dnl
+
+AC_DEFUN([AM_MAFW_PLUGIN_CHECK],
+[
+ AC_MSG_CHECKING(for MAFW plugin)
+
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_LIBS="$LIBS"
+ ac_save_CC="$CC"
+
+ CFLAGS="$CFLAGS $(pkg-config mafw --cflags)"
+ LIBS="$LIBS $(pkg-config mafw --libs)"
+ CC="libtool --mode=link gcc"
+
+ AC_TRY_RUN([
+#include <libmafw/mafw.h>
+
+int main ()
+{
+ MafwRegistry *registry = NULL;
+ gboolean result;
+
+ g_type_init();
+
+ registry = MAFW_REGISTRY(mafw_get_local_registry());
+ if (!registry) {
+ printf ("Cannot get registry\n");
+ return 1;
+ }
+ result = mafw_local_registry_load_plugin(MAFW_LOCAL_REGISTRY(registry), $1, NULL);
+ if (!result) {
+ printf ("Unable to load %s\n", $1);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+ ], [$2], [$3])
+
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
+ CC="$ac_save_CC"
+])
--- /dev/null
+lib_LTLIBRARIES = libcpmpsubtitles.la
+
+libcpmpsubtitles_la_SOURCES = cpmpsubtitles.c
+libcpmpsubtitles_la_LIBADD = $(MAFW_SUBTITLES_CPA_LIBS)
+libcpmpsubtitles_la_CPPFLAGS = $(MAFW_SUBTITLES_CPA_CFLAGS)
+libcpmpsubtitles_la_LDFLAGS = module -avoid-version
+
+libdir = $(CPA_PLUGINDIR)
+
+desktop_DATA = cpmpsubtitles.desktop
+desktopdir = $(CPA_DESKTOPDIR)
+EXTRA_DIST = $(desktop_DATA)
--- /dev/null
+/*
+ * Subtitles control panel applet.
+ * Copyright (C) 2010 Roman Moravcik
+ *
+ * encodings structure imported from totem-subtitle-encoding.c
+ * Copyright (C) 2001-2006 Bastien Nocera <hadess@hadess.net>
+ *
+ * font family detection imported from hildon-font-selection-dialog.c
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+
+#include <gtk/gtk.h>
+#include <hildon/hildon.h>
+#include <hildon-cp-plugin/hildon-cp-plugin-interface.h>
+
+#include <gconf/gconf-client.h>
+
+#define GCONF_MAFW_GST_SUBTITLE_RENDERER "/system/mafw/mafw-gst-subtitles-renderer"
+#define _HL(str) dgettext("hildon-libs",str)
+
+typedef enum
+{
+ FONT_STYLE_REGULAR,
+ FONT_STYLE_ITALIC,
+ FONT_STYLE_BOLD,
+ FONT_STYLE_ITALIC_BOLD,
+ FONT_STYLE_LAST,
+} FontStyleIndex;
+
+typedef struct {
+ int index;
+ const char *name;
+} FontStyle;
+
+static FontStyle font_styles[] = {
+ {FONT_STYLE_REGULAR, N_("Regular")},
+ {FONT_STYLE_ITALIC, N_("Italic")},
+ {FONT_STYLE_BOLD, N_("Bold")},
+ {FONT_STYLE_ITALIC_BOLD, N_("Italic Bold")}
+};
+
+static const gint font_sizes[] =
+{
+ 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, -1
+};
+
+typedef enum
+{
+ SUBTITLE_ENCODING_ISO_8859_6,
+ SUBTITLE_ENCODING_IBM_864,
+ SUBTITLE_ENCODING_MAC_ARABIC,
+ SUBTITLE_ENCODING_WINDOWS_1256,
+
+ SUBTITLE_ENCODING_ARMSCII_8,
+
+ SUBTITLE_ENCODING_ISO_8859_4,
+ SUBTITLE_ENCODING_ISO_8859_13,
+ SUBTITLE_ENCODING_WINDOWS_1257,
+
+ SUBTITLE_ENCODING_ISO_8859_14,
+
+ SUBTITLE_ENCODING_ISO_8859_2,
+ SUBTITLE_ENCODING_IBM_852,
+ SUBTITLE_ENCODING_MAC_CE,
+ SUBTITLE_ENCODING_WINDOWS_1250,
+
+ SUBTITLE_ENCODING_GB18030,
+ SUBTITLE_ENCODING_GB2312,
+ SUBTITLE_ENCODING_GBK,
+ SUBTITLE_ENCODING_HZ,
+
+ SUBTITLE_ENCODING_BIG5,
+ SUBTITLE_ENCODING_BIG5_HKSCS,
+ SUBTITLE_ENCODING_EUC_TW,
+
+ SUBTITLE_ENCODING_MAC_CROATIAN,
+
+ SUBTITLE_ENCODING_ISO_8859_5,
+ SUBTITLE_ENCODING_IBM_855,
+ SUBTITLE_ENCODING_ISO_IR_111,
+ SUBTITLE_ENCODING_KOI8_R,
+ SUBTITLE_ENCODING_MAC_CYRILLIC,
+ SUBTITLE_ENCODING_WINDOWS_1251,
+
+ SUBTITLE_ENCODING_CP_866,
+
+ SUBTITLE_ENCODING_MAC_UKRAINIAN,
+ SUBTITLE_ENCODING_KOI8_U,
+
+ SUBTITLE_ENCODING_GEOSTD8,
+
+ SUBTITLE_ENCODING_ISO_8859_7,
+ SUBTITLE_ENCODING_MAC_GREEK,
+ SUBTITLE_ENCODING_WINDOWS_1253,
+
+ SUBTITLE_ENCODING_MAC_GUJARATI,
+
+ SUBTITLE_ENCODING_MAC_GURMUKHI,
+
+ SUBTITLE_ENCODING_ISO_8859_8_I,
+ SUBTITLE_ENCODING_IBM_862,
+ SUBTITLE_ENCODING_MAC_HEBREW,
+ SUBTITLE_ENCODING_WINDOWS_1255,
+
+ SUBTITLE_ENCODING_ISO_8859_8,
+
+ SUBTITLE_ENCODING_MAC_DEVANAGARI,
+
+ SUBTITLE_ENCODING_MAC_ICELANDIC,
+
+ SUBTITLE_ENCODING_EUC_JP,
+ SUBTITLE_ENCODING_ISO_2022_JP,
+ SUBTITLE_ENCODING_SHIFT_JIS,
+
+ SUBTITLE_ENCODING_EUC_KR,
+ SUBTITLE_ENCODING_ISO_2022_KR,
+ SUBTITLE_ENCODING_JOHAB,
+ SUBTITLE_ENCODING_UHC,
+
+ SUBTITLE_ENCODING_ISO_8859_10,
+
+ SUBTITLE_ENCODING_MAC_FARSI,
+
+ SUBTITLE_ENCODING_ISO_8859_16,
+ SUBTITLE_ENCODING_MAC_ROMANIAN,
+
+ SUBTITLE_ENCODING_ISO_8859_3,
+
+ SUBTITLE_ENCODING_TIS_620,
+
+ SUBTITLE_ENCODING_ISO_8859_9,
+ SUBTITLE_ENCODING_IBM_857,
+ SUBTITLE_ENCODING_MAC_TURKISH,
+ SUBTITLE_ENCODING_WINDOWS_1254,
+
+ SUBTITLE_ENCODING_UTF_7,
+ SUBTITLE_ENCODING_UTF_8,
+ SUBTITLE_ENCODING_UTF_16,
+ SUBTITLE_ENCODING_UCS_2,
+ SUBTITLE_ENCODING_UCS_4,
+
+ SUBTITLE_ENCODING_ISO_8859_1,
+ SUBTITLE_ENCODING_ISO_8859_15,
+ SUBTITLE_ENCODING_IBM_850,
+ SUBTITLE_ENCODING_MAC_ROMAN,
+ SUBTITLE_ENCODING_WINDOWS_1252,
+
+ SUBTITLE_ENCODING_TCVN,
+ SUBTITLE_ENCODING_VISCII,
+ SUBTITLE_ENCODING_WINDOWS_1258,
+
+ SUBTITLE_ENCODING_CURRENT_LOCALE,
+
+ SUBTITLE_ENCODING_LAST
+} SubtitleEncodingIndex;
+
+typedef struct {
+ int index;
+ const char *charset;
+ const char *name;
+} SubtitleEncoding;
+
+static SubtitleEncoding encodings[] = {
+ {SUBTITLE_ENCODING_ISO_8859_6, "ISO-8859-6", N_("Arabic")},
+ {SUBTITLE_ENCODING_IBM_864, "IBM864", N_("Arabic")},
+ {SUBTITLE_ENCODING_MAC_ARABIC, "MAC_ARABIC", N_("Arabic")},
+ {SUBTITLE_ENCODING_WINDOWS_1256, "WINDOWS-1256", N_("Arabic")},
+
+ {SUBTITLE_ENCODING_ARMSCII_8, "ARMSCII-8", N_("Armenian")},
+
+ {SUBTITLE_ENCODING_ISO_8859_4, "ISO-8859-4", N_("Baltic")},
+ {SUBTITLE_ENCODING_ISO_8859_13, "ISO-8859-13", N_("Baltic")},
+ {SUBTITLE_ENCODING_WINDOWS_1257, "WINDOWS-1257", N_("Baltic")},
+
+ {SUBTITLE_ENCODING_ISO_8859_14, "ISO-8859-14", N_("Celtic")},
+
+ {SUBTITLE_ENCODING_ISO_8859_2, "ISO-8859-2", N_("Central European")},
+ {SUBTITLE_ENCODING_IBM_852, "IBM852", N_("Central European")},
+ {SUBTITLE_ENCODING_MAC_CE, "MAC_CE", N_("Central European")},
+ {SUBTITLE_ENCODING_WINDOWS_1250, "WINDOWS-1250", N_("Central European")},
+
+ {SUBTITLE_ENCODING_GB18030, "GB18030", N_("Chinese Simplified")},
+ {SUBTITLE_ENCODING_GB2312, "GB2312", N_("Chinese Simplified")},
+ {SUBTITLE_ENCODING_GBK, "GBK", N_("Chinese Simplified")},
+ {SUBTITLE_ENCODING_HZ, "HZ", N_("Chinese Simplified")},
+
+ {SUBTITLE_ENCODING_BIG5, "BIG5", N_("Chinese Traditional")},
+ {SUBTITLE_ENCODING_BIG5_HKSCS, "BIG5-HKSCS", N_("Chinese Traditional")},
+ {SUBTITLE_ENCODING_EUC_TW, "EUC-TW", N_("Chinese Traditional")},
+
+ {SUBTITLE_ENCODING_MAC_CROATIAN, "MAC_CROATIAN", N_("Croatian")},
+
+ {SUBTITLE_ENCODING_ISO_8859_5, "ISO-8859-5", N_("Cyrillic")},
+ {SUBTITLE_ENCODING_IBM_855, "IBM855", N_("Cyrillic")},
+ {SUBTITLE_ENCODING_ISO_IR_111, "ISO-IR-111", N_("Cyrillic")},
+ {SUBTITLE_ENCODING_KOI8_R, "KOI8-R", N_("Cyrillic")},
+ {SUBTITLE_ENCODING_MAC_CYRILLIC, "MAC-CYRILLIC", N_("Cyrillic")},
+ {SUBTITLE_ENCODING_WINDOWS_1251, "WINDOWS-1251", N_("Cyrillic")},
+
+ {SUBTITLE_ENCODING_CP_866, "CP866", N_("Cyrillic/Russian")},
+
+ {SUBTITLE_ENCODING_MAC_UKRAINIAN, "MAC_UKRAINIAN", N_("Cyrillic/Ukrainian")},
+ {SUBTITLE_ENCODING_KOI8_U, "KOI8-U", N_("Cyrillic/Ukrainian")},
+
+ {SUBTITLE_ENCODING_GEOSTD8, "GEORGIAN-PS", N_("Georgian")},
+
+ {SUBTITLE_ENCODING_ISO_8859_7, "ISO-8859-7", N_("Greek")},
+ {SUBTITLE_ENCODING_MAC_GREEK, "MAC_GREEK", N_("Greek")},
+ {SUBTITLE_ENCODING_WINDOWS_1253, "WINDOWS-1253", N_("Greek")},
+
+ {SUBTITLE_ENCODING_MAC_GUJARATI, "MAC_GUJARATI", N_("Gujarati")},
+
+ {SUBTITLE_ENCODING_MAC_GURMUKHI, "MAC_GURMUKHI", N_("Gurmukhi")},
+
+ {SUBTITLE_ENCODING_ISO_8859_8_I, "ISO-8859-8-I", N_("Hebrew")},
+ {SUBTITLE_ENCODING_IBM_862, "IBM862", N_("Hebrew")},
+ {SUBTITLE_ENCODING_MAC_HEBREW, "MAC_HEBREW", N_("Hebrew")},
+ {SUBTITLE_ENCODING_WINDOWS_1255, "WINDOWS-1255", N_("Hebrew")},
+
+ {SUBTITLE_ENCODING_ISO_8859_8, "ISO-8859-8", N_("Hebrew Visual")},
+
+ {SUBTITLE_ENCODING_MAC_DEVANAGARI, "MAC_DEVANAGARI", N_("Hindi")},
+
+ {SUBTITLE_ENCODING_MAC_ICELANDIC, "MAC_ICELANDIC", N_("Icelandic")},
+
+ {SUBTITLE_ENCODING_EUC_JP, "EUC-JP", N_("Japanese")},
+ {SUBTITLE_ENCODING_ISO_2022_JP, "ISO2022JP", N_("Japanese")},
+ {SUBTITLE_ENCODING_SHIFT_JIS, "SHIFT-JIS", N_("Japanese")},
+
+ {SUBTITLE_ENCODING_EUC_KR, "EUC-KR", N_("Korean")},
+ {SUBTITLE_ENCODING_ISO_2022_KR, "ISO2022KR", N_("Korean")},
+ {SUBTITLE_ENCODING_JOHAB, "JOHAB", N_("Korean")},
+ {SUBTITLE_ENCODING_UHC, "UHC", N_("Korean")},
+
+ {SUBTITLE_ENCODING_ISO_8859_10, "ISO-8859-10", N_("Nordic")},
+
+ {SUBTITLE_ENCODING_MAC_FARSI, "MAC_FARSI", N_("Persian")},
+
+ {SUBTITLE_ENCODING_ISO_8859_16, "ISO-8859-16", N_("Romanian")},
+ {SUBTITLE_ENCODING_MAC_ROMANIAN, "MAC_ROMANIAN", N_("Romanian")},
+
+ {SUBTITLE_ENCODING_ISO_8859_3, "ISO-8859-3", N_("South European")},
+
+ {SUBTITLE_ENCODING_TIS_620, "TIS-620", N_("Thai")},
+
+ {SUBTITLE_ENCODING_ISO_8859_9, "ISO-8859-9", N_("Turkish")},
+ {SUBTITLE_ENCODING_IBM_857, "IBM857", N_("Turkish")},
+ {SUBTITLE_ENCODING_MAC_TURKISH, "MAC_TURKISH", N_("Turkish")},
+ {SUBTITLE_ENCODING_WINDOWS_1254, "WINDOWS-1254", N_("Turkish")},
+
+ {SUBTITLE_ENCODING_UTF_7, "UTF-7", N_("Unicode")},
+ {SUBTITLE_ENCODING_UTF_8, "UTF-8", N_("Unicode")},
+ {SUBTITLE_ENCODING_UTF_16, "UTF-16", N_("Unicode")},
+ {SUBTITLE_ENCODING_UCS_2, "UCS-2", N_("Unicode")},
+ {SUBTITLE_ENCODING_UCS_4, "UCS-4", N_("Unicode")},
+
+ {SUBTITLE_ENCODING_ISO_8859_1, "ISO-8859-1", N_("Western")},
+ {SUBTITLE_ENCODING_ISO_8859_15, "ISO-8859-15", N_("Western")},
+ {SUBTITLE_ENCODING_IBM_850, "IBM850", N_("Western")},
+ {SUBTITLE_ENCODING_MAC_ROMAN, "MAC_ROMAN", N_("Western")},
+ {SUBTITLE_ENCODING_WINDOWS_1252, "WINDOWS-1252", N_("Western")},
+
+ {SUBTITLE_ENCODING_TCVN, "TCVN", N_("Vietnamese")},
+ {SUBTITLE_ENCODING_VISCII, "VISCII", N_("Vietnamese")},
+ {SUBTITLE_ENCODING_WINDOWS_1258, "WINDOWS-1258", N_("Vietnamese")},
+
+ {SUBTITLE_ENCODING_CURRENT_LOCALE, NULL, N_("Current Locale")}
+};
+
+static gboolean
+gconf_get_bool (GConfClient *client,
+ const gchar *key)
+{
+ gboolean value = FALSE;
+ gchar *tmp = NULL;
+
+ tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key);
+
+ value = gconf_client_get_bool (client, tmp, NULL);
+
+ if (tmp)
+ g_free (tmp);
+
+ return value;
+}
+
+static void
+gconf_set_bool (GConfClient *client,
+ const gchar *key,
+ gboolean value)
+{
+ gchar *tmp = NULL;
+
+ tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key);
+
+ gconf_client_set_bool (client, tmp, value, NULL);
+
+ if (tmp)
+ g_free (tmp);
+}
+
+static gchar *
+gconf_get_string (GConfClient *client,
+ gchar *key)
+{
+ gchar *value = FALSE;
+ gchar *tmp = NULL;
+
+ tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key);
+
+ value = gconf_client_get_string (client, tmp, NULL);
+
+ if (tmp)
+ g_free (tmp);
+
+ return value;
+}
+
+static void
+gconf_set_string (GConfClient *client,
+ gchar *key,
+ const gchar *value)
+{
+ gchar *tmp = NULL;
+
+ tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key);
+
+ if (value)
+ gconf_client_set_string (client, tmp, value, NULL);
+ else
+ gconf_client_unset (client, tmp, NULL);
+
+ if (tmp)
+ g_free (tmp);
+}
+
+static gboolean
+is_internal_font (const gchar * name)
+{
+ /* FIXME Extremally BAD BAD BAD way of doing things */
+
+ return strcmp (name, "DeviceSymbols") == 0
+ || strcmp(name, "Nokia Smiley") == 0;
+}
+
+static void
+filter_out_internal_fonts (PangoFontFamily **families,
+ int *n_families)
+{
+ int i;
+ int n; /* counts valid fonts */
+ const gchar * name = NULL;
+
+ for (i = 0, n = 0; i < * n_families; i++) {
+ name = pango_font_family_get_name (families[i]);
+
+ if(!is_internal_font(name)) {
+ if (i != n) { /* there are filtered out families */
+ families[n] = families[i]; /* shift the current family */
+ }
+ n++; /* count one more valid */
+ }
+ } /* foreach font family */
+
+ *n_families = n;
+}
+
+static int
+cmp_families (const void *a,
+ const void *b)
+{
+ const char *a_name = pango_font_family_get_name (* (PangoFontFamily **) a);
+ const char *b_name = pango_font_family_get_name (* (PangoFontFamily **) b);
+
+ return g_utf8_collate (a_name, b_name);
+}
+
+static int
+cmp_encodings (const void *a,
+ const void *b)
+{
+ const SubtitleEncoding *a_encoding = (SubtitleEncoding *) a;
+ const SubtitleEncoding *b_encoding = (SubtitleEncoding *) b;
+
+ return g_utf8_collate (_(a_encoding->name), _(b_encoding->name));
+}
+
+static void
+font_selector_dialog (HildonButton *button,
+ gpointer user_data)
+{
+ GtkWidget *dialog, *hbox, *family_selector, *style_selector, *size_selector;
+ gint index = 0;
+ const gchar *font = NULL;
+ PangoFontDescription *font_desc = NULL;
+ PangoFontFamily **families;
+ gint n_families = 0;
+ PangoWeight pango_weight;
+ PangoStyle pango_style;
+
+ font = hildon_button_get_value (HILDON_BUTTON (button));
+ if (font == NULL)
+ return;
+
+ font_desc = pango_font_description_from_string (font);
+
+ dialog = gtk_dialog_new ();
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Font"));
+ gtk_dialog_add_button(GTK_DIALOG (dialog), "OK", GTK_RESPONSE_ACCEPT);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 400);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+
+ /* font family selector */
+ family_selector = hildon_touch_selector_new_text ();
+ gtk_box_pack_start (GTK_BOX (hbox), family_selector, TRUE, TRUE, 0);
+
+ pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (dialog)),
+ &families, &n_families);
+
+ filter_out_internal_fonts (families, &n_families);
+
+ qsort (families, n_families, sizeof(PangoFontFamily *), cmp_families);
+
+ for (index = 0; index < n_families; index++) {
+ const gchar *family = pango_font_family_get_name (families[index]);
+ hildon_touch_selector_insert_text (HILDON_TOUCH_SELECTOR (family_selector),
+ index, family);
+
+ if (strcmp (family, pango_font_description_get_family (font_desc)) == 0) {
+ hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (family_selector), 0,
+ index);
+ hildon_touch_selector_center_on_selected (HILDON_TOUCH_SELECTOR (family_selector));
+ }
+ }
+ g_free (families);
+
+ /* font style selector */
+ style_selector = hildon_touch_selector_new_text ();
+ gtk_widget_set_size_request (style_selector, 200, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), style_selector, FALSE, TRUE, 0);
+
+ index = 0;
+ while (index < FONT_STYLE_LAST) {
+ const gchar *style = g_strdup_printf ("%s", _(font_styles[index].name));
+ hildon_touch_selector_insert_text (HILDON_TOUCH_SELECTOR (style_selector),
+ font_styles[index].index, style);
+ index++;
+ }
+ pango_weight = pango_font_description_get_weight (font_desc);
+ pango_style = pango_font_description_get_style (font_desc);
+
+ if (pango_weight == PANGO_WEIGHT_NORMAL) {
+ if (pango_style == PANGO_STYLE_NORMAL) {
+ hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (style_selector), 0,
+ FONT_STYLE_REGULAR);
+ } else {
+ hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (style_selector), 0,
+ FONT_STYLE_ITALIC);
+ }
+ } else {
+ if (pango_style == PANGO_STYLE_NORMAL) {
+ hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (style_selector), 0,
+ FONT_STYLE_BOLD);
+ } else {
+ hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (style_selector), 0,
+ FONT_STYLE_ITALIC_BOLD);
+ }
+ }
+ hildon_touch_selector_center_on_selected (HILDON_TOUCH_SELECTOR (style_selector));
+
+ /* font size selector */
+ size_selector = hildon_touch_selector_new_text ();
+ gtk_widget_set_size_request (size_selector, 100, -1);
+ gtk_box_pack_start (GTK_BOX (hbox), size_selector, FALSE, TRUE, 0);
+
+ index = 0;
+ while (font_sizes[index] != -1) {
+ const gchar *size = g_strdup_printf ("%d", font_sizes[index]);
+ hildon_touch_selector_insert_text (HILDON_TOUCH_SELECTOR (size_selector),
+ index, size);
+
+ if (font_sizes[index] == (pango_font_description_get_size (font_desc) / PANGO_SCALE)) {
+ hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (size_selector), 0,
+ index);
+ hildon_touch_selector_center_on_selected (HILDON_TOUCH_SELECTOR (size_selector));
+ }
+
+ index++;
+ }
+
+ /* Run the dialog */
+ gtk_widget_show_all (GTK_WIDGET (dialog));
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+ if (font_desc)
+ pango_font_description_free (font_desc);
+
+ font_desc = pango_font_description_new ();
+
+ /* set font family */
+ pango_font_description_set_family (font_desc,
+ hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (family_selector)));
+
+ /* set font style */
+ switch (hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (style_selector), 0)) {
+ case FONT_STYLE_REGULAR:
+ pango_font_description_set_style (font_desc, PANGO_STYLE_NORMAL);
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_NORMAL);
+ break;
+
+ case FONT_STYLE_ITALIC:
+ pango_font_description_set_style (font_desc, PANGO_STYLE_ITALIC);
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_NORMAL);
+ break;
+
+ case FONT_STYLE_BOLD:
+ pango_font_description_set_style (font_desc, PANGO_STYLE_NORMAL);
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+ break;
+
+ case FONT_STYLE_ITALIC_BOLD:
+ pango_font_description_set_style (font_desc, PANGO_STYLE_ITALIC);
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+ break;
+ }
+
+ /* set font size */
+ pango_font_description_set_size (font_desc,
+ font_sizes[hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (size_selector), 0)] * PANGO_SCALE);
+
+ hildon_button_set_value (HILDON_BUTTON (button), pango_font_description_to_string (font_desc));
+ }
+
+ if (font_desc)
+ pango_font_description_free (font_desc);
+
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+}
+
+
+static GtkWidget *
+create_encoding_selector (void)
+{
+ GtkWidget *selector;
+ gint index = 0;
+
+ selector = hildon_touch_selector_new_text ();
+
+ qsort (encodings, SUBTITLE_ENCODING_LAST - 1, sizeof (SubtitleEncoding), cmp_encodings);
+
+ while (index < SUBTITLE_ENCODING_LAST) {
+ const gchar *encoding = NULL;
+
+ if (encodings[index].charset) {
+ encoding = g_strdup_printf ("%s (%s)", _(encodings[index].name),
+ encodings[index].charset);
+ } else {
+ encoding = g_strdup_printf ("%s", _(encodings[index].name));
+ }
+
+ hildon_touch_selector_insert_text (HILDON_TOUCH_SELECTOR (selector),
+ index,
+ encoding);
+ index++;
+ }
+
+ return selector;
+}
+
+static GtkWidget *
+create_autoload_subtitles_button (GConfClient *gconf_client)
+{
+ GtkWidget *button;
+ gboolean autoload_subtitles = FALSE;
+
+ button = hildon_check_button_new (HILDON_SIZE_FINGER_HEIGHT);
+ gtk_button_set_label (GTK_BUTTON (button), _("Automatically load subtitle files"));
+
+ autoload_subtitles = gconf_get_bool (gconf_client, "autoload_subtitles");
+ if (autoload_subtitles)
+ hildon_check_button_set_active (HILDON_CHECK_BUTTON (button), TRUE);
+ else
+ hildon_check_button_set_active (HILDON_CHECK_BUTTON (button), FALSE);
+
+ return button;
+}
+
+static void
+save_autoload_subtitles (GConfClient *gconf_client,
+ GtkWidget *widget)
+{
+ if (hildon_check_button_get_active (HILDON_CHECK_BUTTON (widget)))
+ gconf_set_bool (gconf_client, "autoload_subtitles", TRUE);
+ else
+ gconf_set_bool (gconf_client, "autoload_subtitles", FALSE);
+}
+
+static GtkWidget *
+create_subtitles_font_button (GConfClient *gconf_client)
+{
+ GtkWidget *button;
+ const gchar *font = NULL;
+
+ button = hildon_button_new (HILDON_SIZE_FINGER_HEIGHT,
+ HILDON_BUTTON_ARRANGEMENT_VERTICAL);
+ hildon_button_set_title (HILDON_BUTTON (button), _("Font"));
+ hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 0.0);
+ hildon_button_set_title_alignment (HILDON_BUTTON(button), 0.0, 0.5);
+ hildon_button_set_value_alignment (HILDON_BUTTON (button), 0.0, 0.5);
+ hildon_button_set_style (HILDON_BUTTON (button), HILDON_BUTTON_STYLE_PICKER);
+
+ font = gconf_get_string (gconf_client, "subtitle_font");
+ if (font) {
+ hildon_button_set_value (HILDON_BUTTON (button), font);
+ } else {
+ hildon_button_set_value (HILDON_BUTTON (button), "Sans Bold 18");
+ }
+
+ g_signal_connect (button, "clicked", G_CALLBACK (font_selector_dialog),
+ NULL);
+
+ return button;
+}
+
+static void
+save_subtitles_font (GConfClient *gconf_client,
+ GtkWidget *widget)
+{
+ const gchar *font = NULL;
+
+ font = hildon_button_get_value (HILDON_BUTTON (widget));
+ gconf_set_string (gconf_client, "subtitle_font", font);
+}
+
+static GtkWidget *
+create_subtitles_encoding_button (GConfClient *gconf_client)
+{
+ GtkWidget *button, *selector;
+ const gchar *encoding = NULL;
+
+ button = hildon_picker_button_new (HILDON_SIZE_FINGER_HEIGHT,
+ HILDON_BUTTON_ARRANGEMENT_VERTICAL);
+ hildon_button_set_title (HILDON_BUTTON (button), _("Encoding"));
+ hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 0.0);
+ hildon_button_set_title_alignment (HILDON_BUTTON(button), 0.0, 0.5);
+ hildon_button_set_value_alignment (HILDON_BUTTON (button), 0.0, 0.5);
+
+ selector = create_encoding_selector ();
+ hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button),
+ HILDON_TOUCH_SELECTOR (selector));
+
+ encoding = gconf_get_string (gconf_client, "subtitle_encoding");
+ if (encoding) {
+ gint index = 0;
+
+ while (index < SUBTITLE_ENCODING_LAST) {
+ if (encodings[index].charset) {
+ if (strcmp (encodings[index].charset, encoding) == 0) {
+ hildon_picker_button_set_active (HILDON_PICKER_BUTTON (button),
+ index);
+ break;
+ }
+ }
+ index++;
+ }
+ } else {
+ hildon_picker_button_set_active (HILDON_PICKER_BUTTON (button),
+ SUBTITLE_ENCODING_CURRENT_LOCALE);
+ }
+
+ return button;
+}
+
+static void
+save_subtitles_encoding (GConfClient *gconf_client,
+ GtkWidget *widget)
+{
+ gint encoding = 0, index = 0;
+
+ encoding = hildon_picker_button_get_active (HILDON_PICKER_BUTTON (widget));
+
+ while (index < SUBTITLE_ENCODING_LAST) {
+ if (encoding == index) {
+ gconf_set_string (gconf_client, "subtitle_encoding",
+ encodings[index].charset);
+ break;
+ }
+ index++;
+ }
+}
+
+osso_return_t
+execute (osso_context_t *osso,
+ gpointer data,
+ gboolean user_activated)
+{
+ GConfClient *gconf_client = NULL;
+ GtkWidget *dialog, *vbox, *autoload_subtitles_button;
+ GtkWidget *subtitles_font_button, *subtitles_encoding_button;
+
+ gconf_client = gconf_client_get_default ();
+ if (gconf_client == NULL) {
+ return OSSO_ERROR;
+ }
+
+ dialog = gtk_dialog_new ();
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data));
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Subtitles"));
+ gtk_dialog_add_button(GTK_DIALOG (dialog), _HL("wdgt_bd_save"), GTK_RESPONSE_ACCEPT);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
+
+ /* autoload subtitles button */
+ autoload_subtitles_button = create_autoload_subtitles_button (gconf_client);
+ gtk_box_pack_start (GTK_BOX (vbox), autoload_subtitles_button, TRUE, TRUE, 0);
+
+ /* font selector */
+ subtitles_font_button = create_subtitles_font_button (gconf_client);
+ gtk_box_pack_start (GTK_BOX (vbox), subtitles_font_button, TRUE, TRUE, 0);
+
+ /* font encoding */
+ subtitles_encoding_button = create_subtitles_encoding_button (gconf_client);
+ gtk_box_pack_start (GTK_BOX (vbox), subtitles_encoding_button, TRUE, TRUE, 0);
+
+ /* Run the dialog */
+ gtk_widget_show_all (GTK_WIDGET (dialog));
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+ /* save autoload subtitles option */
+ save_autoload_subtitles (gconf_client, autoload_subtitles_button);
+
+ /* save subtitle font option */
+ save_subtitles_font (gconf_client, subtitles_font_button);
+
+ /* save subtitle encoding option */
+ save_subtitles_encoding (gconf_client, subtitles_encoding_button);
+ }
+
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+ return OSSO_OK;
+}
+
+osso_return_t
+save_state (osso_context_t *osso,
+ gpointer data)
+{
+ return OSSO_OK;
+}
+
--- /dev/null
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Name=Subtitles
+Comment=Control panel to configure subtitles for mafw-gst-subtitles-renderer
+Type=HildonControlPanelPlugin
+Icon=general_video_file
+X-control-panel-plugin=libcpmpsubtitles.so
+X-Text-Domain=mafw-gst-subtitles-renderer
+Categories=extras
--- /dev/null
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+export AUTOMAKE="automake-1.9"
+export ACLOCAL=`echo $AUTOMAKE | sed s/automake/aclocal/`
+
+glib-gettextize --copy --force
+intltoolize --automake --copy --force
+autoreconf -v -f -i || exit 1
+test -n "$NOCONFIGURE" || ./configure \
+ --enable-debug --enable-maintainer-mode "$@"
--- /dev/null
+#
+# configure.ac for MAFW gstreamer renderer library
+#
+# Author: Visa Smolander <visa.smolander@nokia.com>
+#
+# Copyright (C) 2007, 2008, 2009 Nokia. All rights reserved.
+
+AC_PREREQ([2.53])
+AC_INIT([mafw-gst-subtitles-renderer], [0.2.2010.07-2])
+
+AC_CONFIG_SRCDIR([libmafw-gst-renderer/mafw-gst-renderer.h])
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_AUX_DIR([build-aux])
+
+AM_INIT_AUTOMAKE([foreign tar-ustar])
+AM_MAINTAINER_MODE
+
+AC_DISABLE_STATIC
+
+IT_PROG_INTLTOOL([0.35])
+AC_SUBST([GETTEXT_PACKAGE], [mafw-gst-subtitles-renderer])
+AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"], [The domain to use with gettext.])
+AM_GLIB_GNU_GETTEXT()
+
+dnl Prevent AC_PROG_CC adding '-g -O2' to CFLAGS.
+SAVEDCFLAGS="$CFLAGS"
+AC_PROG_CC
+if test "x$GCC" = xyes; then
+ CFLAGS="$SAVEDCFLAGS"
+fi
+
+AC_PROG_LIBTOOL
+AC_PROG_INSTALL
+
+# DISABLED_BY_DEFAULT(NAME, DESCRIPTION)
+# ---------------------------------
+# Creates a new --enable-* option, with default value `no'.
+AC_DEFUN([DISABLED_BY_DEFAULT], [dnl
+ AC_ARG_ENABLE([$1], AS_HELP_STRING([--enable-$1], [$2]), [],[dnl
+ m4_bpatsubst([enable_$1], [[^0-9a-z]], [_])=no])dnl
+])# DISABLED_BY_DEFAULT
+
+# ENABLED_BY_DEFAULT(NAME, DESCRIPTION)
+# ---------------------------------
+# Creates a new --disable-* option, with default value `yes'.
+AC_DEFUN([ENABLED_BY_DEFAULT], [dnl
+ AC_ARG_ENABLE([$1], AS_HELP_STRING([--disable-$1], [$2]), [],[dnl
+ m4_bpatsubst([enable_$1], [[^0-9a-z]], [_])=yes])dnl
+])# ENABLED_BY_DEFAULT
+
+dnl Prerequisites.
+
+GSTREAMER_VERSION=0.10.20
+
+AM_PATH_GLIB_2_0(2.15.0, [], [], [glib])
+PKG_CHECK_MODULES(DEPS,
+ gobject-2.0 >= 2.0
+ gstreamer-0.10 >= $GSTREAMER_VERSION
+ gstreamer-plugins-base-0.10 >= $GSTREAMER_VERSION
+ mafw >= 0.1
+ libosso >= 2.0
+ x11
+ hal
+ totem-plparser
+ gconf-2.0 >= 2.0
+ gnome-vfs-2.0
+ mce
+ dbus-1
+)
+
+dnl Check for GdkPixbuf, needed for dumping current frame
+GDKPIXBUF_REQUIRED=2.12.0
+AC_ARG_ENABLE(gdkpixbuf,
+ AS_HELP_STRING([--disable-gdkpixbuf],
+ [Disable GdkPixbuf support, required for current frame dumping]),,
+ [enable_gdkpixbuf=auto])
+
+if test "x$enable_gdkpixbuf" != "xno"; then
+ PKG_CHECK_MODULES(GDKPIXBUF,
+ [gdk-pixbuf-2.0 >= $GDKPIXBUF_REQUIRED],
+ [have_gdkpixbuf=yes],
+ [have_gdkpixbuf=no])
+ AC_SUBST(GDKPIXBUF_LIBS)
+ AC_SUBST(GDKPIXBUF_CFLAGS)
+
+ if test "x$have_gdkpixbuf" = "xyes"; then
+ AC_DEFINE(HAVE_GDKPIXBUF, [], [Define if we have GdkPixbuf])
+ fi
+else
+ have_gdkpixbuf="no (disabled)"
+fi
+
+if test "x$enable_gdkpixbuf" = "xyes"; then
+ if test "x$have_gdkpixbuf" != "xyes"; then
+ AC_MSG_ERROR([Couldn't find GdkPixbuf >= $GDKPIXBUF_REQUIRED.])
+ fi
+fi
+
+AM_CONDITIONAL(HAVE_GDKPIXBUF, test "x$have_gdkpixbuf" = "xyes")
+
+
+dnl Check for Conic, needed connection error handling
+CONIC_REQUIRED=0.16
+AC_ARG_ENABLE(conic,
+ AS_HELP_STRING([--disable-conic],
+ [Disable Conic support, required to handle network errors]),,
+ [enable_conic=auto])
+
+if test "x$enable_conic" != "xno"; then
+ PKG_CHECK_MODULES(CONIC,
+ [conic >= $CONIC_REQUIRED],
+ [have_conic=yes],
+ [have_conic=no])
+ AC_SUBST(CONIC_LIBS)
+ AC_SUBST(CONIC_CFLAGS)
+
+ if test "x$have_conic" = "xyes"; then
+ AC_DEFINE(HAVE_CONIC, [], [Define if we have Conic])
+ fi
+else
+ have_conic="no (disabled)"
+fi
+
+if test "x$enable_conic" = "xyes"; then
+ if test "x$have_conic" != "xyes"; then
+ AC_MSG_ERROR([Couldn't find Conic >= $CONIC_REQUIRED.])
+ fi
+fi
+
+AM_CONDITIONAL(HAVE_CONIC, test "x$have_conic" = "xyes")
+
+
+
+plugindir=`$PKG_CONFIG --variable=plugindir mafw`
+AC_SUBST(plugindir)
+
+dnl Default compile flags. (NOTE: CFLAGS is reserved for the user!)
+
+AC_SUBST([_CFLAGS])
+AC_SUBST([_LDFLAGS])
+_CFLAGS="-Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations"
+_CFLAGS="$_CFLAGS -ggdb3"
+
+dnl Configure-time options.
+
+dnl Debugging.
+DISABLED_BY_DEFAULT([debug], [compile with debug flags and extra output])
+if test "x$enable_debug" = xyes; then
+ AC_DEFINE([MAFW_DEBUG], [1], [Enable debugging related parts.])
+ _CFLAGS="$_CFLAGS -O0 -Werror -DGTK_DISABLE_DEPRECATED"
+else
+ AC_DEFINE([G_DEBUG_DISABLE], [1], [Disable g_debug() calls.])
+ _CFLAGS="$_CFLAGS -O2"
+fi
+AS_IF([test "x$enable_debug" = xyes],
+ [AC_DEFINE([MAFW_DEBUG], [1], [Enable extra debug messages])
+ CFLAGS="$CFLAGS -Werror -O0 -ggdb3 -DGTK_DISABLE_DEPRECATED"],
+ [AC_DEFINE([G_DEBUG_DISABLE], [1], [Disable g_debug calls])
+ CFLAGS="$CFLAGS -O2"])
+
+
+dnl Tests.
+DISABLED_BY_DEFAULT([tests], [disable unit tests])
+if test "x${SBOX_DPKG_INST_ARCH}" = "xarmel"; then
+ AC_MSG_WARN([Tests are disabled for compilation in armel])
+ enable_tests="no"
+fi
+if test "x$enable_tests" = xyes; then
+ PKG_CHECK_MODULES(CHECKMORE, [checkmore, check >= 0.9.4])
+ if test -z "$CHECKMORE_LIBS"; then
+ AC_MSG_WARN([checkmore is needed for unit tests!])
+ fi
+fi
+AM_CONDITIONAL(ENABLE_TESTS,
+ [test "x$enable_tests" = xyes && test -n "$CHECKMORE_LIBS"])
+
+dnl Volume handling
+if test "x${SBOX_DPKG_INST_ARCH}" = "xi386"; then
+ DISABLED_BY_DEFAULT([pulse-volume], [enable volume handling with pulse])
+else
+ ENABLED_BY_DEFAULT([pulse-volume], [enable volume handling with pulse])
+fi
+if test "x$enable_pulse_volume" = xno; then
+ AC_DEFINE([MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME], [1], [Disables volume handling with pulse.])
+else
+ PKG_CHECK_MODULES(VOLUME, libpulse-mainloop-glib >= 0.9.15)
+fi
+
+
+dnl Mute
+DISABLED_BY_DEFAULT([mute], [enable mute handling])
+if test "x$enable_mute" = xyes; then
+ AC_DEFINE([MAFW_GST_RENDERER_ENABLE_MUTE], [1], [Enable mute.])
+fi
+
+dnl Tracing.
+DISABLED_BY_DEFAULT([tracing], [enable function instrumentation (tracing)])
+if test "x$enable_tracing" = xyes; then
+ _CFLAGS="$_CFLAGS -finstrument-functions -rdynamic"
+fi
+
+dnl Coverage.
+DISABLED_BY_DEFAULT([coverage], [enable coverage data generation (gcov)])
+if test "x$enable_coverage" = xyes; then
+ AC_PATH_PROG(LCOV, [lcov], [lcov])
+ if test "x$LCOV" = x; then
+ echo You need to install lcov to get actual reports!
+ echo See http://ltp.sf.net/coverage/lcov.php
+ fi
+ if test "x$SBOX_USE_CCACHE" == xyes; then
+ AC_MSG_ERROR([Please set SBOX_USE_CCACHE=no to use coverage.])
+ fi
+ _CFLAGS="$_CFLAGS -fprofile-arcs -ftest-coverage"
+ _LDFLAGS="$_LDFLAGS -g -lgcov"
+fi
+AM_CONDITIONAL(ENABLE_COVERAGE,
+ [test "x$enable_coverage" != xno && test -n "$LCOV"])
+
+dnl Control Panel
+PKG_CHECK_MODULES([MAFW_SUBTITLES_CPA], [libosso >= 2.0
+ hildon-1 >= 2.1
+ hildon-control-panel
+ gtk+-2.0
+ gconf-2.0])
+
+CPA_PLUGINDIR=`pkg-config hildon-control-panel --variable=pluginlibdir`
+CPA_DESKTOPDIR=`pkg-config hildon-control-panel --variable=plugindesktopentrydir`
+
+AC_SUBST(MAFW_SUBTITLES_CPA_CFLAGS)
+AC_SUBST(MAFW_SUBTITLES_CPA_LIBS)
+AC_SUBST(CPA_DESKTOPDIR)
+AC_SUBST(CPA_PLUGINDIR)
+
+dnl Output files.
+
+AC_CONFIG_FILES([
+ Makefile
+ mafw-gst-renderer-uninstalled.pc
+ libmafw-gst-renderer/Makefile
+ applet/Makefile
+ tests/Makefile
+ debian/mafw-gst-subtitles-renderer.install
+ po/Makefile.in
+])
+
+AC_OUTPUT
--- /dev/null
+mafw-gst-subtitles-renderer (0.3.2010.24-1+0m5-2) unstable; urgency=low
+
+ * Fixed Bug: 6438: Plugin makes background music stop on lock screen.
+ The only solution to fix this problem was rename back MAFW GStreamer
+ renderer from mafw-gst-subtitles-renderer to mafw-gst-renderer.
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 26 Oct 2010 14:50:06 +0200
+
+mafw-gst-subtitles-renderer (0.3.2010.24-1+0m5-1) unstable; urgency=low
+
+ * Package updated to version mafw-gst-renderer-0.3.2010.24-1+0m5.
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Mon, 25 Oct 2010 12:58:00 +0200
+
+mafw-gst-renderer (0.3.2010.24-1+0m5) unstable; urgency=low
+
+ * This entry has been added by BIFH queue processor
+ version has been changed to 0.3.2010.24-1+0m5
+
+ -- Pekka Rönkkö <ext-pekka.1.ronkko@nokia.com> Mon, 21 Jun 2010 14:57:08 +0300
+
+mafw-gst-renderer (0.3.2010.24-1) unstable; urgency=low
+
+ * Fixes: NB#161636 - Playbin sends EOS for endless stream
+
+ -- Pekka Rönkkö <ext-pekka.1.ronkko@nokia.com> Thu, 17 Jun 2010 12:05:30 +0200
+
+mafw-gst-subtitles-renderer (0.2.2010.07-2+0m5-3) unstable; urgency=low
+
+ * This package should depend on gstreamer0.10-plugins-base-subtitles
+ version (>= 0.10.25-0maemo14+0m5-1).
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 25 May 2010 17:12:33 +0200
+
+mafw-gst-subtitles-renderer (0.2.2010.07-2+0m5-2) unstable; urgency=low
+
+ * Updated Finnish translation by mikuu.
+ * Installation of this package disable mafw-gst-renderer instead of replacing it.
+ (original mafw-gst-renderer will be re-enabled after uninstallation of package).
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 18 May 2010 14:35:42 +0200
+
+mafw-gst-subtitles-renderer (0.2.2010.07-2+0m5-1) unstable; urgency=low
+
+ * Added Hungarian translation by Gyorgy Lakatos.
+ * Package updated to version mafw-gst-renderer-0.2.2010.07-2+0m5-1.
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Wed, 5 May 2010 10:12:28 +0200
+
+mafw-gst-renderer (0.2.2010.07-2) unstable; urgency=low
+
+ * Fixes: NB#156757 - Volume settings can't be changed via Volume key, Media player is playing, Tklock is On.
+
+ -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Wed, 17 Feb 2010 10:09:38 +0200
+
+mafw-gst-renderer (0.2.2010.06-1) unstable; urgency=low
+
+ * Fixes: NB#150064 - NP-Video:Frames not changing while performing seek operation when the video is in paused state
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Wed, 10 Feb 2010 21:43:22 +0200
+
+mafw-gst-renderer (0.2.2010.01-1) unstable; urgency=low
+
+ * Version number increased in trunk.
+ * A forbidden word removed from debian/changelog.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Thu, 07 Jan 2010 19:36:53 +0200
+
+mafw-gst-renderer (0.2.2009.52-2) unstable; urgency=low
+
+ * Version number increased.
+
+ -- Tuomas Kamarainen <tuomas.kamarainen@nokia.com> Wed, 23 Dec 2009 12:40:45 +0200
+
+mafw-gst-renderer (0.2.2009.52-1) unstable; urgency=low
+
+ * Fixes: NB#149945 - mafw-gst-renderer leaks some GStreamer messages
+ * Thanks to Mueller Tim for the patch.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Sun, 20 Dec 2009 22:43:29 +0200
+
+mafw-gst-renderer (0.2.2009.50-2) unstable; urgency=low
+
+ * Fixes: NB#148080 - Device UI becomes very slow after long time usage of Media Player
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Thu, 10 Dec 2009 19:07:45 +0200
+
+mafw-gst-renderer (0.2.2009.50-1) unstable; urgency=low
+
+ * Version and changelog updated for pre-release 0.2009.50-1
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Tue, 08 Dec 2009 09:21:47 +0200
+
+mafw-gst-renderer (0.2.2009.49-1) unstable; urgency=low
+
+ * Rebuild for 2009.49-1.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Tue, 01 Dec 2009 19:27:31 +0200
+
+mafw-gst-renderer (0.2.2009.48-2) unstable; urgency=low
+
+ * Pre-release PR 1.2 2009.48-2 tag.
+
+ -- Tuomas Kämäräinen <tuomas.kamarainen@nokia.com> Fri, 27 Nov 2009 11:56:14 +0200
+
+mafw-gst-renderer (0.2.2009.48-1) unstable; urgency=low
+
+ * Pre-release PR 1.2 2009.48-1 tag.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Tue, 24 Nov 2009 21:57:59 +0200
+
+mafw-gst-renderer (0.1.2009.47-2) unstable; urgency=low
+
+ * Version increased.
+
+ -- Tuomas Kamarainen <tuomas.kamarainen@nokia.com> Fri, 20 Nov 2009 13:26:19 +0300
+
+mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-5) unstable; urgency=low
+
+ * Added Danish translation by Joe Hansen.
+ * Added Finnish translation by Marko Vertainen.
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 16 Feb 2010 15:02:02 +0100
+
+mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-4) unstable; urgency=low
+
+ * Added German translation by Philipp Zabel.
+ * Backup/restore original mafw-gst-renderer on installation/uninstallation
+ of mafw-gst-subtitles package.
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Wed, 27 Jan 2010 15:29:27 +0100
+
+mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-3) unstable; urgency=low
+
+ * Updating of mafw-gst-subtitles-applet package was not updating
+ mafw-gst-subtitles-renderer package too.
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 19 Jan 2010 15:53:19 +0100
+
+mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-2) unstable; urgency=low
+
+ * Added Czech translation.
+ * List of available encoding was not sorted.
+ * Removed mafw-gst-subtitles-applet postinst/postrm script, because
+ mafw is restared during mafw-gst-subtitles-renderer instalation.
+ * Added more font sizes.
+ * Nokia fonts removed from the list of filtered fonts.
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Tue, 19 Jan 2010 15:07:48 +0100
+
+mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-1) unstable; urgency=low
+
+ * Added missing build dependency to hildon-control-panel-dev
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Mon, 18 Jan 2010 22:39:17 +0100
+
+mafw-gst-subtitles-renderer (0.1.2009.47-1+0m5-0) unstable; urgency=low
+
+ * Added subtitles support.
+ * Added Subtitles control panel applet.
+
+ -- Roman Moravcik <roman.moravcik@gmail.com> Mon, 18 Jan 2010 22:09:11 +0100
+
+mafw-gst-renderer (0.1.2009.42-2) unstable; urgency=low
+
+ * Version increased.
+
+ -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Tue, 20 Oct 2009 13:26:36 +0300
+
+mafw-gst-renderer (0.1.2009.42-1) unstable; urgency=low
+
+ * Version and changelog updated for pre-release 0.2009.42-1
+ * Rebuild needed.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Mon, 12 Oct 2009 17:21:48 +0300
+
+mafw-gst-renderer (0.1.2009.40-1) unstable; urgency=low
+
+ * Version and changelog updated for pre-release 0.2009.40-1
+ * PR_1_1_baseline copied from trunk.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Sun, 04 Oct 2009 15:47:32 +0300
+
+mafw-gst-renderer (0.1.2009.39-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.39-1
+ * Check for changes only in device having the video-out property.
+ * Disabled test of pulse reconnection as it is not needed with fake volume
+ manager to fix volume test
+ * Changed default fake volume initialization to 0.485 instead of 1 to fix
+ volume tests
+ * Added return of initialized fake volume manager in an idle call to fix
+ volume tests
+ * Added function to reset volume to pulse pipeline in case pulse volume
+ management is disabled
+ * Added fake volume manager and disabled normal handling with pulse when
+ pulse volume is disabled in compilation.
+ * We avoid setting audiosink to the pipeline and native flags when pulse
+ volume is disabled.
+ * Moved checking for pulse dependency to its conditional compilation
+ * Added support for conditional compilation regarding to volume in
+ renderer
+ * Adds a macro to round values when converting from nanoseconds to seconds.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 18 Sep 2009 14:21:32 +0300
+
+mafw-gst-renderer (0.1.2009.37-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.37-1
+ * Fixes: NB#121136 - [Power Management]Device never goto power saving mode when video playback is connected to TV out
+ * Fixes: NB#134730 - [PR1.1 proposal] <MemLeak> mafw-gst-renderer.c
+ * Fixes: NB#134728 - [PR1.1 proposal] <MemLeak> mafw-gst-renderer-worker.c
+ * Fixes: NB#134495 - [PR1.1 proposal] State changed signal does not come sometimes when stream is played
+ * if for some reason client starts a resume operation
+ after a seek on a stream and by the time we get the resume command we
+ have not started buffering yet, make sure we signal the state change
+ to playing to the client.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 04 Sep 2009 12:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.35-3) unstable; urgency=low
+
+ * MAFW Sales RC4.
+ * Fixes: NB#129912 - Audio playback jarring while receiving a SMS while multiple browser/applications are open.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Tue, 25 Aug 2009 14:15:34 +0300
+
+mafw-gst-renderer (0.1.2009.35-2) unstable; urgency=low
+
+ * First MAFW Sales RC.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Fri, 21 Aug 2009 16:38:27 +0300
+
+mafw-gst-renderer (0.1.2009.35-1) unstable; urgency=low
+
+ * Fixes: NB#129912 - Audio playback jarring while receiving a SMS while multiple browser/applications are open.
+ * Increased the priority of the mafw-gst-renderer.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Thu, 20 Aug 2009 17:34:03 +0300
+
+mafw-gst-renderer (0.1.2009.34-3) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.34-3
+ * Fixes: NB#132950 - Video seeking is slow most of the time
+ * Check if we get a different duration that the source one and update it
+ if needed in renderer
+ * Added function mafw_gst_renderer_update_source_duration
+ * Reworked mafw_gst_renderer_increase_playcount to use _get_source function
+ * Reworked mafw_gst_renderer_get_metadata to use _get_source function
+ * Created _get_source function in renderer
+ * Reworked _check_duration condition into two different ifs and extracted
+ duration in seconds calculation
+ * Added duration to the source metadata request and kept it in the
+ renderer metadata structure.
+ * Duration in renderer converted in gint instead of guint to hold
+ negative values
+ * flag GST_SEEK_FLAG_KEY_UNIT.
+ * Patch provided by Rene Stadler.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Mon, 17 Aug 2009 22:06:17 +0300
+
+mafw-gst-renderer (0.1.2009.33-3) unstable; urgency=low
+
+ * Fixes: NB#131655 - UPnP: Playback starts from the first instead of playing from where we paused if left the device idle
+ * Fixes: NB#131609 - Mafw-dbus-wrapper crashes. Audio cannot be heard from device's loudspeaker.
+ * Replaced assertion with critical in volume manager for unsuccessful
+ setting volume in pulse operations.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Thu, 13 Aug 2009 17:03:10 +0300
+
+
+mafw-gst-renderer (0.1.2009.33-2) unstable; urgency=low
+
+ * Fixes: NB#128110 - Playback neither stopped nor internal mmc is mounted onto pc when connected in mass storage mode
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Mon, 10 Aug 2009 12:27:43 +0300
+
+mafw-gst-renderer (0.1.2009.33-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.33-1
+ * Fixes: NB#128110 - Playback neither stopped nor internal mmc is mounted onto pc when connected in mass storage mode
+ * New Build-Dependency libosso-gnomevfs2-dev added.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Wed, 05 Aug 2009 12:37:05 +0300
+
+mafw-gst-renderer (0.1.2009.32-1) unstable; urgency=low
+
+ * MAFW, pre-release 0.1.2009.32-1
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Sun, 02 Aug 2009 22:32:27 +0300
+
+mafw-gst-renderer (0.1.2009.30-3) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.30-3
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Wed, 22 Jul 2009 14:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.30-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.30-2
+ * Fixes: NB#128479 - Seeking in UPnP signals pause and keeps on playing
+ * Solved problem when pausing while buffering in renderer worker
+ * We activate state changes if we resume while buffering to report the
+ state change to playing in renderer worker
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Wed, 22 Jul 2009 14:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.30-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.30-1
+ * Added more debug to the _handle_buffering function in renderer worker
+ * Just set pipeline to playing when finished buffering of a stream when
+ seeking to avoid signalling PAUSE.
+ * Added documentation in _handle_state_changed function in renderer worker
+ * Added comments in _do_play function in renderer worker
+ * Added comments in _finalize_startup funcion in renderer worker
+ * Reworked _handle_state_changed to use GST_STATE_TRANSITION in renderer
+ worker.
+ * Reworked _handle_state_changed to use _do_pause in renderer worker
+ * Created _do_pause function to notify the state change and get the
+ current frame on pause if needed in renderer worker.
+ * Removed buffering info from renderer as it was being handled by worker
+ * Removed seek in pause comments as we are not using them in renderer worker
+ * Simplified if condition in state managegement in renderer worker.
+ * Removed state assignment because it could be done at one point in
+ _handle_state_changed in renderer worker.
+ * Added comments in field names in renderer worker to clarify their use
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 17 Jul 2009 14:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.28-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.28-2
+ * Ref the assigned playlist
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Tue, 07 Jul 2009 14:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.28-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.28-1
+ * Fixes: NB#123689 - mafw-dbus-wrapper-76CE-6-4559.rcore.lzo crashed
+ * Ref the assigned playlist
+ * Removing an unnecessary comparison.
+ * Added g_debug in volume manager to indicate that it is initialized and
+ return the instance
+ * Changed _connect function to get an InitCbCallback in volume manager
+ * Modified _reconnect function in volume manager to receive an
+ InitCbCallback and propertly return the volume manager if reconnection
+ happens before having connected a first time
+ * Written function to create the InitCbClosure in volume manager
+ * When [re-]connection to pulse fails, we log a critical and reconnect
+ after 1 second
+ * Modified log in renderer tests to log only errors
+ * Added tests for pulseaudio reconnection in renderer
+ * Removed volume tests in playing since it is not needed anymore as it
+ does not depend on the playing state.
+ * Added check for receiving mute when property is changed in renderer
+ tests
+ * In renderer tests, wait for the volume manager to be initialized when
+ testing properties
+ * Added pulseaudio mock to renderer tests
+ * Added small code comment in renderer tests
+ * Solved problem with mute not enable in renderer tests
+ * Fixed problem when adding elements to a mock playlist in renderer
+ tests
+ * Fixed problem with playlist size initialization in playlist iterator in
+ renderer that was causing problems in the tests
+ * Fixed a bug in the tests when testing the stats updating
+ * Fixed problem with playlist reference count in renderer tests.
+ * Replaced pulsesink and xvimagesink by fakesink in renderer tests
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 03 Jul 2009 11:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.27-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.27-2
+ * Fixes: NB#123701 - mafw-dbus-wrapper-76CE-6-1218.rcore.lzo crashed
+ * Fixes: NB#116836 - Streaming stops after taping on Next button during paused state
+ * Fixes: NB#123545 - mafw-gst-renderer get-position returns uninitialized value
+ * Fixes: NB#124469 - Device going to power saving mode after seek for video streams
+ * Fixes: NB#124116 - Position not progressing after seeking
+ * Fixes: NB#117860 - Inability to handle multiple resource of UPnP items
+ * Make sure we stay paused while buffering.
+ * Always keep worker->state up-to-date.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Tue, 30 Jun 2009 14:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.27-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.27-1
+ * Added function to remove the _set_timeout and used not to call it twice
+ innecessarily.
+ * Changed the order of adding the timeout to set the volume to pulse and
+ calling the timeout immediately as that runs on the mainloop and that
+ execution is delayed to that
+ * Checked for NULL operation when writing volume to pulse to avoid
+ crashes. Critical used instead.
+ * In _ext_stream_restore2_read_cb changed assertion for critical when
+ getting eol < 0 in volume manager
+ * Discarded ext_stream_restore2 volume event when eol < 0. Crash avoided
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Thu, 25 Jun 2009 13:40:00 +0300
+
+mafw-gst-renderer (0.1.2009.26-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.26-1
+ * Check for NULL in the current_metadata.
+ * Removed useles warning message
+ * Updating states and blanking even if we do not need to report them.
+ * Move pause notification from _do_play to handle_buffering.
+ * Build fix.
+ * make _get_position be a state dependant function.
+ On Transitioning it sets position to 0, on Stopped raises an error.
+ * Improved state management in mafw-gst-renderer
+ when seeking (compare new state with worker state to decide
+ if we have to ignore the state transition and in any case,
+ always update the worker state).
+ * Activate playbin2 flags. Speeds up video start time to half.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Tue, 23 Jun 2009 14:33:24 +0300
+
+mafw-gst-renderer (0.1.2009.25-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.25-2
+ * Fixes: NB#117207 - Random MAFW-DBUS-WRAPPER crashes observed
+ * Fixes: NB#104213 - 'Unable to Find Media file' information note not displayed when MMC removed.
+ * Fixes: NB#116426 - Renderer fails to go to pause state when media clips are seeked while streaming
+ * Fixes: NB#121545 - pa_context_connect fails though flag PA_CONTEXT_NOFAIL set
+ * Fixes: NB#120942 - State changed signal is not coming when play issued right after seeking with video streams
+ * Extended current metadata function.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Mon, 15 Jun 2009 14:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.25-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.25-1
+ * Reconnection to pulse is done using an idle call in volume manager.
+ * If PLAY is issued rigtht after seek,
+ signal the state change when we are done buffering. Still,
+ there is a problem because we should not execute a PLAY command
+ while buffering...
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 12 Jun 2009 11:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.24-3) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.24-3
+ * Fixes: NB#118019 - Playing a clip of Unsupported format will stop the playback.
+ * Fixes: NB#120378 - Video doesn't start to play when clicked
+ * Stop setting volume if pulse is down in volume manager
+ * Written small workaround for problem when getting an empty error while
+ saving a pixbuf in renderer worker.
+ * Log a warning message when processing an error.
+ * A mafw-gst-renderer dependency version shortened to 0.9.15-1.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Wed, 10 Jun 2009 11:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.24-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.24-2
+ * Added "mafw_renderer_get_current_metadata" function to the API.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Mon, 08 Jun 2009 11:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.24-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.24-1
+ * Fixes: NB#120287 - Video recorded using other camera (e.g. Canon, Pentax) not playing smooth
+ * Fixed debug for seekability in renderer.
+ * We check always GStreamer seekability unless it is reported FALSE from
+ source.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Thu, 04 Jun 2009 10:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.23-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.23-2
+ * Fixes: NB#119440 - Dbus wrapper crashes when high bit rate, high resolution clips are played.
+ * Fixes: NB#119613 - Random mafw-dbus-wrapper coredump generated after booting.
+ * Fixes: NB#119467 - Deleted playlists are not freed.
+ * Fixes: NB#118459 - Cannot play Nokia 5800 video clip
+ * Fixes: NB#115776 - Renderer state changed signal are not coming when playing and seeking video
+ * No need to ref the playlist in the renderer,
+ the playlist manager does that already.
+ * Changed to avoid setting the timeout if neither volume nor mute have
+ changed in volume manager
+ * Changed debug messages in volume manager
+ * We ignore mute if it not enabled (default = not enabled).
+ * Added option to configure.ac to disable or enable mute handling
+ * Use g_error_new_literal if string is constant.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Tue, 02 Jun 2009 12:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.23-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.23-1
+ * Signalling volume when reconnecting to pulse
+ * Added code to reconnect to pulse when it gets disconnected.
+ * Closure callback for initialization is not called if it is NULL in
+ volume manager.
+ * Created _connect function to connect with pulse and reworker the init
+ function in volume manager.
+ * Created _destroy_context function and changed _destroy_idle function to
+ do it in volume manager.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 29 May 2009 10:30:00 +0300
+
+mafw-gst-renderer (0.1.2009.22-3) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.22-3
+ * Use appropriate error codes when the renderer cannot create
+ the playback pipeline and when there are problems with the
+ video window.
+ * Abort the renderer if cannot create pipeline ot sinks.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Wed, 27 May 2009 10:30:00 +0300
+
+mafw-gst-renderer (0.1.2009.22-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.22-2
+ * Fixes: NB#114972 - NP: AUdio- Taping on Next or Previous song volume goes to 0 level
+ * Fixes: NB#109166 - NP view - Volume bar does not popup for Hardware volume +/- key presses
+ * Fixes: NB#116070 - video plays before displaying unsupported resolution error message
+ * Fixes: NB#112697 - gst-renderer not listening volume change events from pulseaudio
+ * Fixes: NB#118001 - seekbar is disabled after playing a unsupported clip
+ * We switch volume manager volume to the just set so we signal it directly
+ when the change is requested. We don't signal any change in the volume
+ subscription if we have and operation in progress.
+ * We keep the pa_operation when writing the volume and cancel it and unref
+ it when a new one comes.
+ * Changed requested_* structure members to current_* in volume manager
+ * Renamed volume and mute structure members to pulse_* in volume manager.
+ * Fixed a small problem with mute. We were forgetting to set it when
+ sending it to pulse.
+ * Changed timeout interval for setting volume to 200ms.
+ * We just change the volume as soon as we get the first call and then we
+ add the timeout to filter following changes.
+ * Improved rounding volumes as we signalled different ones from the one we
+ were setting.
+ * Added protections to public methods so that they are not called when
+ volume manager is not alive yet.
+ * Minor changes when falling back to playbin usage.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Mon, 25 May 2009 12:21:24 +0300
+
+mafw-gst-renderer (0.1.2009.22-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.22-1
+ * If we fallback to use playbin instead of playbin2, check that
+ we can actually create an instance before attempting to
+ set properties.
+ * Changed to filter volume and mute changes to join several in a single
+ call.
+ * Setting property to ensure pulse role when initializing volume manager
+ in renderer.
+ * Separated role and its prefix for checking in volume manager in renderer
+ * Added more debug to volume manager in renderer
+ * Added dependencies to debian/control and configure.ac
+ * Migrated volume management in worker to use pulse implementation.
+ * Added code to manage volume with pulse. This code was developed in
+ collaboration with Marc-André Lureau in gitorious. Link:
+ http://gitorious.org/~calvaris/mafw-pulse/calvaris
+ * Added compilation of volume files to Makefile.am in renderer.
+ * Added empty files with licenses for volume management in renderer.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 22 May 2009 12:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.21-4) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.21-4
+ * Reuse video sink component, do not create a new one every time
+ we play something.
+ * Ref audio and video sink before setting them, since we want them
+ to persist after the pipeline has been destroyed.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Wed, 20 May 2009 11:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.21-3) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.21-3
+ * Fixes: NB#104494 - Missing renderer error when video clib has high framerate
+ * Fixes: NB#115514 - UPnP:After seeking the seekbar on Pause state audio/video clip started playing
+ * Fixes: NB#115304 - Video playback will stop if we plug in usb cable
+ * Fixes: NB#115299 - Media player seek bar comes to starting position if usb cable is pluged in
+ * Properly initialize variable.
+ * Use specific error codes for unsupported
+ resolution and unsupported fps conditions.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Tue, 19 May 2009 10:30:00 +0300
+
+mafw-gst-renderer (0.1.2009.21-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.21-2
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Mon, 18 May 2009 11:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.21-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.21-1
+ * Fixes: NB#117015 - video plays in windowed mode
+ * Fixes: NB#100842 - seeking in aac over http fails
+ * Fixes: NB#115126 - Media Player abuses Tracker API while playing songs
+ * Do not reuse video sink for now, somehow it gets
+ broken after some time and as a result we cannot set XID of target
+ video window to use.
+ * Create and configure audio and video sinks once, then provide these
+ to playbin2 when a new pipeline is created.
+ * Changed _handle_duration to use _check_duration and added for
+ seekability too.
+ * Reworked _query_duration_and_seekability into _check_duration and _check
+ seekability.
+ * Added timeout to query duration and seekability and changed when it was
+ called.
+ * Set timeout id to 0 when timeout is removed
+ * Used function to compare duration in seconds instead of comparing pure
+ nano seconds.
+ * Added function to compare durations in seconds.
+ * Query duration and seek after buffering is complete.
+ * Reworked adding the timeout to use a function.
+ * Modified seekability emission to be done only with changes and adapted
+ to type changes.
+ * Modified duration emission to be emitted only with changes.
+ * Media seekability initialized to unknown when playback begins.
+ * SeekabilityType renamed and moved to renderer worker.
+ * Renderer worker seekability uses its type now instead of gboolean.
+ * Stored duration and seek timeout id to be able to remove it later in
+ renderer worker.
+ * Added query for duration and seekability some seconds after going to
+ PLAYING to have more accurate information from GStreamer in renreder
+ worker.
+ * Reworked _finalize_startup in renderer worker into _finalize_startup and
+ _query_duration_and_seekability. The first uses now the second.
+ * Set pulse sink's latency-time property to half of buffer-time,
+ this provides double buffering capabilities and should also help
+ with avoiding audio glitches. Also, removed buffering for volume
+ pipeline, since that is not needed.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Thu, 14 May 2009 10:09:18 +0300
+
+mafw-gst-renderer (0.1.2009.20-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.20-1
+ * Fixes: NB#107221 - Connecting and disconnecting with an AP while playing an MP3 cause audio breakage
+ * Fixes: NB#114181 - Video aspect ratio is not preserved
+ * Set appropriate buffering settings for audio sink
+ to avoid audio glitches on certain scenarios.
+ * Maintainer changed in control file.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Thu, 07 May 2009 11:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.19-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.19-1
+ * Fixes: NB#108833 - [Onsite] Audio volume is turned full when song is changed
+ * Fixes: NB#113464 - Dbus connection lost error message displayed in while trying to up/down volume level from MTG
+ * Fixes: NB#96483 - Gstreamer renderer does not change from GST_STATE_PAUSED to GST_STATE_READY after timeout
+ * Fixes: NB#104494 - Missing renderer error when video clib has high framerate
+ * Fixes: NB#110654 - mafw-dbus-wrapper prints about a critical error
+ * Fixes: NB#103987 - Audio playback is breaking for few seconds while playing mms live streams.
+ * Fixes power management issues caused by the volume pipeline
+ being always in PAUSED state. While a proper implementation
+ for volume management is not in place, this temporal fix
+ workarounds the problem by setting it to PAUSED on demand
+ when global volume has to be read, and then setting it back
+ to READY.
+ * Do not check video caps on prepare-xwindow-id, instead wait
+ for prerolling to finish, otherwise caps are not set yet.
+ * Use 'g_timeout_add_seconds' where possible.
+ * Added monitor volume hack again, but when going to playing instead of
+ stopping.
+ * Revert "Added monitor_hack again but called only when stopping the worker."
+ * Added monitor_hack again but called only when stopping the worker.
+ * Revert "Added dirty hack to be aware of the volume changes that don't
+ happen"
+ * Revert "Hack to monitor volume does not return TRUE, but FALSE and
+ reinstalls"
+ * Improved playlist-change handling
+ * Hack to monitor volume does not return TRUE, but FALSE and reinstalls
+ the timeout not to do it at regular intervals, but a timeout after last
+ callback is run.
+ * Do not go to PLAYING state until we are done buffering.
+ * Disable native flags in playbin2 temporarily since this is causing
+ trouble with some videos. Also, allow videos with resolution
+ up to 848x576.
+ * Added dirty hack to be aware of the volume changes that don't happen
+ inside mafw code. As soon as GStreamer adds notify::volume signals, we
+ have to remove this immediately.
+ * Setting volume when playing is done only for playback volume.
+ * Moved volume management from playback pipeline to volume pipeline. We
+ don't update the volume pipeline because it should be updated but we do it
+ with the playback one because it has always to be set up.
+ * Moved listening to volume signals from playback pipeline to volume
+ pipeline in renderer
+ * Added customized pipeline to always listen to volume changes in renderer
+ * Added support to distinguish between audio and video codec errors.
+ * Fixed critical warning message.
+ * When we get the ckey coming from the sync bus to the async bus, we check
+ the caps and raise an error if they are not suitable.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Thu, 30 Apr 2009 10:00:00 +0300
+
+mafw-gst-renderer (0.1.2009.18-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.18-1
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Thu, 23 Apr 2009 15:30:00 +0300
+
+mafw-gst-renderer (0.1.2009.17-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.17-2
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 17 Apr 2009 09:18:07 +0300
+
+mafw-gst-renderer (0.1.2009.17-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.17-1
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Wed, 15 Apr 2009 15:59:15 +0300
+
+mafw-gst-renderer (0.1.2009.16-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.16-2
+ * Fixes: NB#110043 - Mafw-dbus-wrapper crash is observed while switching between proxy playlist in a particular case
+ * Fixes: NB#108725 - DLNA CTT tool gives a failed verdict on "MT HTTP Header: Range - use in HEAD/GET requests"
+ * Added pre-unmount signal handling in the renderer.
+ * Added debug for seekability in renderer.
+ * Renderer uses now as first choice seekability coming from source and if not
+ defined, we query GStreamer as it happened so far.
+ * Added requesting seekability to source in renderer.
+ * Added support for seekability coming from source in renderer.
+ * Removed assumption of positive seekability for local files with known
+ duration.
+ * If GStreamer cannot answer to a request for seekability, we assume it is
+ not.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Tue, 14 Apr 2009 15:06:34 +0300
+
+mafw-gst-renderer (0.1.2009.16-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.16-1
+ * All tags reported by Gst are referenced and freed later on,
+ when they have emitted to clients. However, _emit_renderer_art
+ was obtaining a reference to a tag value and freeing that
+ reference when done, leading to a double unref later on.
+
+ -- Mika Tapojärvi <mika.tapojarvi@sse.fi> Wed, 08 Apr 2009 12:41:14 +0300
+
+mafw-gst-renderer (0.1.2009.15-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.15-2
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 03 Apr 2009 09:17:14 +0300
+
+mafw-gst-renderer (0.1.2009.15-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.15-1
+ * Fixes: NB#106136 - Metadata not shown properly for radio stations.
+ * Added transport-actions property. For the moment contains information
+ about Seek operation.
+ * Unit test disabled by default for system integration purposes.
+ * Some tags are detected when Gstreamer is already
+ in GST_STATE_PLAYING, so in this case, emit them right away, otherwise
+ they are never emitted to the UI.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 03 Apr 2009 09:17:14 +0300
+
+mafw-gst-renderer (0.1.2009.14-4) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.14-4
+ * Update playcount id should be 0 while _notify_play is run in renderer
+ so it doesn have sense checking about that
+ * Removed update_playcount_needed as behavior can be accoplished only with
+ timeout id in renderer.
+ * Moved the code to remove the update_playcount to the state class to fix
+ state pattern.
+ * _update_playcount_cb made public inside the renderer to be called from other
+ parts of it.
+ * Moved the code to add the timeout to state-transitioning.
+ * Moved the code from the state notify_eos in the base renderer to the
+ state-playing.
+ * Added initialization of the update_playcount structures in renderer.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Wed, 01 Apr 2009 09:34:16 +0300
+
+mafw-gst-renderer (0.1.2009.14-3) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.14-3
+ * Fixes: NB#107595 - Xid not set error comes when video is played to the end and then played again with media player
+ * Removed guessing the seekability from renderer in favor of only GStreamer
+ query.
+ * Setting pipeline to NULL without checking for async changes as it
+ cannot happen according to Stefan comments.
+ * Must always stop() on EOS when there are
+ no more items to play. This frees X resources if playing video,
+ otherwise setting a new Xid afterward leads to a BadWindow X
+ error.
+ * Enabling gstreamer optimization flags
+ * Creating pipeline at startup and, soon after the playback has ended, to
+ speed up the starting of the playback
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Tue, 31 Mar 2009 09:20:00 +0200
+
+mafw-gst-renderer (0.1.2009.14-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.14-2
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Mon, 30 Mar 2009 09:23:13 +0200
+
+mafw-gst-renderer (0.1.2009.14-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.14-1
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Fri, 27 Mar 2009 09:30:00 +0200
+
+mafw-gst-renderer (0.1.2009.13-5) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.13-5
+ * Fixes: NB#102972 - Pause AAC clip from UPnP server timer shows as 00:00
+ * Changed _notify_buffer_status in state-transitioning in renderer
+ to use the do_notify_buffer status as code was the same after removing timer
+ * Removed timer support from renderer utils
+ * Removed timer handling in renderer.
+ * Removed timer use from renderer get_position
+ * Changed API to return gint instead if guint in the get_position
+ callback
+ * Set Visa as integrator.
+ * Upgrade copyright year.
+ * Add headers for Makefile.am and configure.ac files.
+ * Set Visa Smolander as the contact person in headers.
+
+ -- Juha Kellokoski <veitikka6@gmail.com> Thu, 26 Mar 2009 09:53:00 +0200
+
+mafw-gst-renderer (0.1.2009.13-4) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.13-4
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Wed, 25 Mar 2009 09:16:48 +0200
+
+mafw-gst-renderer (0.1.2009.13-3) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.13-3
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Tue, 24 Mar 2009 09:23:08 +0200
+
+mafw-gst-renderer (0.1.2009.12-4) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.12-4
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Wed, 18 Mar 2009 09:17:01 +0200
+
+mafw-gst-renderer (0.1.2009.12-3) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.12-3
+ * Fixed CID 610
+ * Fixed CID 2592
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Wed, 18 Mar 2009 09:17:01 +0200
+
+mafw-gst-renderer (0.1.2009.12-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.12-2
+ * Fixes: NB#102172 - Total clip duration shown wrongly for vbr clips.
+ * Fixes: NB#105468 - Mafw-dbus-wrapper freezes when commands are given consecutively
+ * Corrected the double tag emission when pausing in transitioning
+ and going to GST_STATE_READY in renderer worker
+ * Moved _free_taglist functions above in renderer worker
+ * Removed tag_list as global variable to be inside the renderer
+ worker
+ * Modified other functions according this point
+ * Moved _add_ready_timeout from _construct_pipeline to _do_play
+ in renderer to allow us going to ready just after building the pipeline
+ because in the other case we hadn't received the seekability yet.
+ * Solved a memory leak when freeing the tag list in renderer worker
+ * Changed going to GST_STATE_READY only for seekable streams in renderer
+ worker
+ * Code to go to GST_STATE_READY after sometime in PAUSED in renderer
+ worker reactivated
+ * Added checks for NULL buffers when emitting the current frame on
+ paused.
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Tue, 17 Mar 2009 09:21:54 +0200
+
+mafw-gst-renderer (0.1.2009.11-6) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.11-6
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 12 Mar 2009 09:13:36 +0200
+
+mafw-gst-renderer (0.1.2009.11-5) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.11-5
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 12 Mar 2009 09:13:36 +0200
+
+mafw-gst-renderer (0.1.2009.11-4) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.11-4
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Wed, 11 Mar 2009 09:09:57 +0200
+
+mafw-gst-renderer (0.1.2009.11-3) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.11-3
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Tue, 10 Mar 2009 09:12:41 +0200
+
+mafw-gst-renderer (0.1.2009.11-2) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.11-2
+ * Fixes: NB#104680 - System UI freezed while playing high resolution albumart clips
+ * Added buffering info test in renderer
+ * Added support to get buffering information in renderer tests
+ * Added tests for properties management in renderer tests
+ * Solved a problem that could cause some race conditions in volume handling
+ in renderer worker
+ * Moved _set_volume and _set_mute functions in the worker file in
+ renderer.
+ * Added support to manage properties values in renderer tests
+ * Added test for duration emission in renderer tests
+ * Added test for get_position in renderer
+ * Added tests for media art emission in renderer
+ * Added GStreamer tag management in renderer tests
+ * Added testframe.png to renderer tests
+ * Activated and fixed video tests compilation in renderer
+ * Added functions to metadata checks in renderer tests.
+ * Added error policy tests in renderer
+ * Added support in renderer tests to receive expected error callbacks
+ * Fixed problem with update lastplayed in renderer tests.
+ * Solved problem in playcount renderer tests.
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Mon, 09 Mar 2009 09:24:38 +0200
+
+mafw-gst-renderer (0.1.2009.11-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.11-1
+ * Notify when third-party applications modify gstreamer volume.
+ * Enabling unit tests to mafw-gst-renderer.
+ * Update playcount and last-played when reaching EOS, or after 10 seconds.
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 05 Mar 2009 14:43:54 +0200
+
+mafw-gst-renderer (0.1.2009.10-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.10-1
+ * Fixed segfault
+ * Removed gstreamer0.10-selector from the mafw-gst-renderer dependencies.
+ * Allow blanking when TV Out cable is plugged.
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 26 Feb 2009 14:06:24 +0200
+
+mafw-gst-renderer (0.1.2009.9-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.09-1
+ * Disabling optimization flags
+ * Removing helixbin usage
+ * Delaying metadatas received from gstreamer
+ * Preload some gst plugins at startup
+ * Adding some optimization flags to the pipeline
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 19 Feb 2009 17:26:04 +0200
+
+mafw-gst-renderer (0.1.2009.8-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.08-1
+ * Fixes: NB#98725
+ * Fixes: NB#100158
+ * Added Nokia copyright to gstcreenshot.[ch] files in renderer.
+ * Made bvw_frame_conv_convert asynchronous
+ * Adapted renderer worker to that conversion.
+ * Reusing pipeline for color space conversion in renderer.
+ * Changed raw video art saving to use bacon video widget conversion in
+ mafw-gst-renderer
+ * Added gstsnapshot.[ch] files to renderer to convert raw frames into
+ understandable format for gdk_pixbuf
+ * Changed tmp file name for gstreamer renderer emitted art
+ * Changed function _save_graphic_file_from_gst_buffer to
+ save an unconverted video/x-raw-rgb.
+ * Revert "Fake function that copies a fake frame to test"
+
+ -- Juha Kellokoski <ext-juha.kellokoski@nokia.com> Thu, 12 Feb 2009 14:22:39 +0200
+
+mafw-gst-renderer (0.1.2009.07-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.07-1
+ * Changed highest resolution for fremantle
+
+ -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Fri, 06 Feb 2009 08:38:37 +0200
+
+mafw-gst-renderer (0.1.2009.06-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.06-1
+ * Changed highest resolution for fremantle
+ * Added GTK_DISABLE_DEPRECATED parameters for mafw-tracker-source
+ configure.ac. Added extended descriptions for
+ * mafw-gst-renderer.
+ * Build fix
+
+ -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Fri, 30 Jan 2009 14:03:15 +0200
+
+mafw-gst-renderer (0.1.2009.05-1) unstable; urgency=low
+
+ * MAFW gst renderer, pre-release 0.2009.05-1
+ * Changing the base class of the extension objects to GInitiallyUnowned
+ * Changed testframe.jpeg
+
+ -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Thu, 22 Jan 2009 14:33:27 +0200
+
+mafw-gst-renderer (0.1.2009.04-1) unstable; urgency=low
+
+ * MAFW, pre-release 0.2009.04-1
+ * Changed testframe.jpeg
+ * Reducing lintian warnings.
+ * Fixes: NB#97304
+ * Fixes: NB#94990
+ * Fixes: NB#85894
+
+ -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Fri, 16 Jan 2009 14:59:38 +0200
+
+mafw-gst-renderer (0.1.2009.03-1) unstable; urgency=low
+
+ * MAFW, pre-release 0.1.2009.03-1
+ * Testing the error reporting when resuming in transitioning state
+ without having paused.
+ * Sent a GError if trying to resume in transitioning state without
+ having paused before.
+ * Reset timer when stopping.
+ * Remated stream_timer_* functions into media_timer_* because
+ name was confusing.
+ * Renamed _is_playlist into uri_is_playlist and moved to -utils in
+ renderer.
+ * Changed its calls to use the new name.
+ * Changed condition about reporting the error when performing _do_seek.
+ * Added comment about the playlist mode error handling in renderer
+ worker.
+ * Changed tagmap array for a GHashTable in renderer worker.
+ * Removed playback mode and pl struct from global variables and added
+ to worker structure.
+ * Added worker as parameter to _reset_pl_info and _on_pl_entry_parsed
+ in renderer because it is needed to use the parameters inside worker structure.
+ * Removed old_error handler because it was not being used.
+ * In renderer worker renamed:
+ * NORMAL_MODE -> WORKER_MODE_SINGLE_PLAY
+ * PLAYLIST_MODE -> WORKER_MODE_PLAYLIST
+ * Changed _metadata_set_cb to g_debug if operation was correct or if
+ it failed.
+ * Reindented _update_playcount_metadata_cb parameters in renderer.
+ * Logged error in _update_playcount_metadata_cb in renderer because
+ it was just being ignored. This causes the tests to log the warning.
+ * Added a meaningful error to a test in renderer.
+ * Fixed _update_playcount_metadata_cb documentation in renderer.
+ * Renamed _playcount_metadata into _update_playcount_metadata_cb in
+ renderer.
+ * mafw_gstreamer_renderer_get_position changed not to test for
+ callback != NULL because it is already being checked in preconditions.
+ * Changed mafw_gstreamer_renderer_get_status not to test callback != NULL
+ because it is already checked in preconditions.
+ * In mafw_gstreamer_renderer_get_status added check for callback != NULL
+ in preconditions.
+ * Renamed unable_play_count into play_failed_count in renderer.
+ * Added G_LOG_DOMAIN for check-mafw-gstreamer-renderer.
+ * Removed the CHECK-MLS traces from renderer tests.
+ * Changed the G_LOG_DOMAIN for given files to have more suitable ones
+ in renderer.
+
+ -- Mika Tapojärvi <ext-mika.tapojarvi@nokia.com> Thu, 08 Jan 2009 16:13:10 +0200
+
+mafw-gst-renderer (0.1.2008.52-1) unstable; urgency=low
+
+ * Renamed midas to mafw
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 22 Dec 2008 12:55:59 +0200
+
+midas-gstreamer-renderer (0.1.2008.52) unstable; urgency=low
+
+ * Removing libtotem-pl-parser
+ * Deactivated code of the timeout to go to ready until bug with gstreamer is clarified.
+ * Added functions to add, remove and timeout function itself to switch from PAUSED to READY in renderer worker.
+ Used this functions to implement the behavior when pausing.
+ * Fixes NB#85894 incorrect duration reported
+ * Fixes NB#93484 Playlist format other than wpl and ram shows its icon incorrectly in Playlists container
+ * Fixes NB#94990 Gstreamer renderer gives seekable metadata TRUE for radio stream
+
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 19 Dec 2008 15:28:58 +0200
+
+midas-gstreamer-renderer (0.1.2008.51-1) unstable; urgency=low
+
+ * (ha)xmas: hardwire ximagesink is removed
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 15 Dec 2008 12:55:59 +0200
+
+midas-gstreamer-renderer (0.1.2008.51) unstable; urgency=low
+
+ * (ha)xmas: hardwire ximagesink temporarily
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 12 Dec 2008 14:57:37 +0200
+
+midas-gstreamer-renderer (0.1.2008.50) unstable; urgency=low
+
+ * Added get_last_index method the the mock playlist in renderer
+ tests.
+ * Added new test cases for various use cases.
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 05 Dec 2008 13:29:06 +0200
+
+midas-gstreamer-renderer (0.1.2008.49) unstable; urgency=low
+
+ * In development.
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 28 Nov 2008 14:35:35 +0200
+
+midas-gstreamer-renderer (0.1.2008.48) unstable; urgency=low
+
+ * In renderer:
+ --Renamed _get_graphic_file_path into _get_tmp_file_from_pool and
+ changed to use the tmp files pool.
+ --Replaced the calls to use _get_tmp_file_from_pool with the
+ proper changes to parameters and return values.
+ * Added resume operation to transitioning state in renderer that
+ allows to resume in transitioning.
+ * Added stop after pausing while transitioning to finish process in a better
+ way in renderer tests.
+ * Implemented HAL listener which stops renderer when usb cable is plugged
+ in, and we are playing something from memory card
+ * Changed do_next and do_prev to begin playback if pressing next
+ or prev when going beyond the playlist limits in renderer.
+ * Added mechanism to start/stop wrappers on package install/removal
+ (ignoring scratchbox support for now). Uses DSME.
+ Added an Xsession.post script.
+ Updated affected components
+ * Fixes: NB#92843 MidasRenderer ""playlist-changed"" and ""media-changed"" signals occur in random order when changing playlist
+ * Fixes: NB#92238 Play state not preserved when next pressed in the end of the playlist.
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 21 Nov 2008 16:59:53 +0200
+
+midas-gstreamer-renderer (0.1.2008.47) unstable; urgency=low
+
+ * Send error signal when handling playback errors.
+ * Added conic network detection in renderer
+ * Added error handing in renderer for CODEC_NOT_FOUND , seek error, network errors, DRM errors.
+ * Fixes: NB#87297 Property of shuffle operation not reflected to the last item of playlist
+ * Fixes: NB#87354 shuffle not applied to dynamically added clips
+ * Fixes: NB#87667 Midas-playlist-daemon crashes with repeat mode 'on' & playing unsupported clip
+ * Fixes: NB#91530 Media-changed signal comes everytime item is added to playlist
+ * Fixes: NB#91566 glib criticals observed when audio playback is stopped
+ * Fixes: NB#87841 Next and previous gives ""Index out of bounds error"" on last and first items
+ * Fixes: NB#91893 local sink crashes when invalid playlist items are played
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 14 Nov 2008 12:30:41 +0200
+
+midas-gstreamer-renderer (0.1.2008.46) unstable; urgency=low
+
+ * Fixes: NB#91061 gstreamer-gnomevfs pkgs missing.
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 07 Nov 2008 11:58:32 +0200
+
+midas-gstreamer-renderer (0.1.2008.45) unstable; urgency=low
+
+ * Implemented move_to_last based on playlist get_last_index function
+ * Implemented tag emission of renderer art in MidasGstreamerRenderer.
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 31 Oct 2008 14:14:16 +0200
+
+midas-gstreamer-renderer (0.1.2008.44) unstable; urgency=low
+
+ * Added support to request the current frame
+ * Added support for the property in the renderer and its storage on the worker.
+ * added gdkpixbuf dependency.
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 24 Oct 2008 10:11:52 +0300
+
+midas-gstreamer-renderer (0.1.2008.43) unstable; urgency=low
+
+ * Renaming local-sink->midas-gstreamer-renderer
+ * support of playback on diablo
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 17 Oct 2008 15:03:14 +0300
+
+midas-gstreamer-renderer (0.1.2008.42) unstable; urgency=low
+
+ * Fixes: NB#89265 unable to parse wpl playlist format files in local sink
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 10 Oct 2008 16:10:02 +0300
+
+midas-gstreamer-renderer (0.1.2008.40) unstable; urgency=low
+
+ * Using playbin2.
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 29 Sep 2008 07:02:28 +0000
+
+midas-gstreamer-renderer (0.1.2008.39) unstable; urgency=low
+
+ * Fixes: NB#87723 Play item pointer switches back to first item of playlist while repeat mode of playlist is not enabled
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Sun, 21 Sep 2008 18:35:06 +0300
+
+midas-gstreamer-renderer (0.1.2008.38) unstable; urgency=low
+
+ * Unit tests fixed after the use_count API addition.
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 15 Sep 2008 08:11:12 +0300
+
+midas-gstreamer-renderer (0.1.2008.37) unstable; urgency=low
+
+ * small face-lift (configure.ac, Makefile.am:s and build fixes)
+ * Fixes: NB#86160 Media continues to play after deleting the playlist
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 08 Sep 2008 08:37:04 +0300
+
+midas-gstreamer-renderer (0.1.2008.36) unstable; urgency=low
+
+ * Fixes: NB#87757 Seeking gives unknown seek mode as error in callback function
+ * Fixes: NB#87414 Seek option is not enabled for mp3 format files
+ * Fixes: NB#87463 playback is switched back to 20 seconds time stamp when the forward button is pressed
+ * Fixes: NB#87524 Video full screen turns blank during pause playback state
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Mon, 01 Sep 2008 08:21:43 +0300
+
+midas-gstreamer-renderer (0.1.2008.35) unstable; urgency=low
+
+ * In development.
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Sun, 24 Aug 2008 19:42:40 +0300
+
+midas-gstreamer-renderer (0.1.2008.34) unstable; urgency=low
+
+ * More strict parameter checking by set_position().
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Fri, 15 Aug 2008 09:48:16 +0300
+
+midas-gstreamer-renderer (0.1.2008.33) unstable; urgency=low
+
+ * Initial release.
+ * Fixes: NB#85491 stop() in transitioning state
+ * Fixes: NB#85894 incorrect duration reported
+ * Fixes: NB#85481 Unable to seek attached mp3 file using MAFW api
+ * Fixes: NB#85675 sink::metadata-changed signal reports the is-seekable key in integer
+ * Fixes: NB#86692 local-sink doesn't emit buffering-info signals
+ * Fixes: NB#85161 attempts to play media having unsupported format results in error message
+ * Fixes: NB#85160 GLIB CRITICAL message trying to get the iradio-name metadata from gstreamer
+ * Fixes: NB#85892 Pausing resets playback
+ * Fixes: NB#85897 media always reported to be unseekable
+ * Fixes: NB#86160 Media continues to play after deleting the playlist
+ * Fixes: NB#86654 crash while playing from a playlist
+ * Fixes: NB#85149 play(callback) is not invoked
+ * Fixes: NB#85150 only the first item of the playlist is played
+ * Fixes: NB#85498 sink should advance to next item if current is unplayable
+ * Fixes: NB#86893 UPnP media content not playing
+ * Fixes: NB#85472 play() starts last play_object()ed item again
+ * Fixes: NB#85475 assign_playlist() starts playing
+ * Fixes: NB#85479 misleading index in media-changed for play_object()
+ * Fixes: NB#85628 crash if invoked without callback
+ * Fixes: NB#87082 gstreamer criticals during playback
+ * Fixes: NB#85489 critical warnings via assign_playlist(NULL)
+ * Fixes: NB#87084 assign_playlist() critical warnings
+ * Fixes: NB#86956 midas-dbus-wrapper dies when playback is attempted in mentioned scenario
+
+ -- Zeeshan Ali <zeeshan.ali@nokia.com> Sun, 10 Aug 2008 19:52:39 +0300
--- /dev/null
+Source: mafw-gst-subtitles-renderer
+Section: misc
+Priority: optional
+Maintainer: Roman Moravcik <roman.moravcik@gmail.com>
+XSBC-Original-Maintainer: Mika Tapojarvi <mika.tapojarvi@sse.fi>
+Build-Depends: debhelper (>= 4.0.0), libglib2.0-dev,
+ libgstreamer0.10-dev (>= 0.10.20-0maemo3),
+ libgstreamer-plugins-base0.10-dev (>= 0.10.20-0maemo5),
+ libx11-dev, libosso-dev (>= 2.0), libmafw0-dev (>= 0.1),
+ checkmore, gstreamer0.10-plugins-base,
+ gstreamer0.10-plugins-good,
+ libhal-dev, libtotem-plparser-dev, libpulse-dev (>= 0.9.15-1),
+ libgconf2-dev, libosso-gnomevfs2-dev, mce-dev,
+ libdbus-1-dev, hildon-control-panel-dev
+Standards-Version: 3.7.2
+Homepage: http://mafwsubrenderer.garage.maemo.org/
+Vcs-Browser: https://garage.maemo.org/plugins/ggit/browse.php/?p=mafwsubrenderer
+Vcs-Git: https://vcs.maemo.org/git/mafwsubrenderer
+
+Package: mafw-gst-subtitles-renderer
+Section: libs
+Architecture: any
+Depends: gconf2, ${shlibs:Depends}, ${misc:Depends}, gstreamer0.10-plugins-base-subtitles (>= 0.10.25-0maemo14+0m5-1)
+Replaces: mafw-gst-renderer
+Description: MAFW gst renderer plugin with subtitles support
+ Renderer plugin for MAFW-gst
+
+Package: mafw-gst-subtitles-renderer-dbg
+Section: devel
+Architecture: any
+Priority: extra
+Depends: mafw-gst-subtitles-renderer (= ${binary:Version})
+Description: debug symbols for mafw-gst-subtitles-renderer
+ MAFW-gst renderer debug symbols
+
+Package: mafw-gst-subtitles-applet
+Section: user/multimedia
+Architecture: any
+Depends: gconf2, ${shlibs:Depends}, ${misc:Depends}, mafw-gst-subtitles-renderer (= ${binary:Version})
+Description: External subtitles support for Media Player
+ Subtitles font and encoding can be change via 'Settings: Subtitles'
+ control panel applet.
+XB-Maemo-Display-Name: Subtitles Support
+XSBC-Bugtracker: https://garage.maemo.org/tracker/?func=add&group_id=1248&atid=4688
+XB-Maemo-Icon-26:
+ iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0
+ d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA9JJREFUeNrsWblOI0EQbVvm
+ FodkIWRDQGAMERIgyxI5IcT+ATbYdEnZYGM23WD5CiDjA5AAOUKYQxY35jK2
+ AZv72Hmt7Va7d46eY4UtTUkjV09NddfrquqjHPj4+CD1TEFS5+QD8AH4AHwA
+ PgBXFJJfBAKB8Orq6o9YLPa1lgzNZrO/ksnkd23jvTYFoFH4+fk59P7+XlMz
+ DZtgm/ZYAiCzs7Okvb2d8vPz8/z90tISWVxc5O2ZmRkyODhI+Z2dHTI3N6ck
+ m5qaIpOTk7w9PT3NeehAlxH0oH93d6cWQqDNzU3S0NBAedETp6enJJ1O8/bt
+ 7S2Xg1eVjY2NVfUryuQxYTzkLy8v6gBEent70+2YtZncqUwmHC5FmdVh0xKA
+ OLjcGWRMrmekkQz9GOWYLLMCEJA/0Fah+PLy8reBgYEvn5m0CJn7+3skL23v
+ 7e39TqVSPzV7dy09cHBwQFTuCb29vaSlpYXyDw8PNEfc0uvrK+np6eGGb2xs
+ 0Bw6Pz9XD6FKpWKY9fIsNTY2cl5Fx4iurq7IyckJXf3YCggqFoskn8+TQqGg
+ DsAsRuUEZ9+JvJ3ZhuGY3aenJ/qutbWVvpfHMOrbEIBKCIlAVXWY4TD67Oys
+ yli9FYoZbwuAmYLsATaYigcwy8fHxzQcZMNFcKIMvFnfrjwgL5VGOjD86OiI
+ XF5eKvUpAnDkAa8A3NzcUMPxq0qYbU9yQCWEZACMv7i4oLNtx/BP84B4XEBi
+ Hh4eksfHR8fLqZ4H/msOYLBSqURDZWtry/VGJi4MYggZ2eM4hGA4wgQ7Jr7F
+ rHtxh/AkhMwQw1AcNRAuw8PDpKuriwPyAoBnSSwDwDEBWz02H73BZNd76QFH
+ OcAUcBbZ39+nce52I3OTA7YB4GSJXbNcLpvmAZutmgqhlZUV0tnZaWswrzzg
+ SRL39/eT7u5uy8Gampr4YODj8bj7Ok8oVAWgr6+Pn1qVAWSzWX5uSSQSVZf6
+ XC7H20NDQ/zsjiTf3t5WkkWjUXoZYrS+vs556ECXkXYTo/q41CgDwC2IVSVG
+ Rkb4e+SEWEHAzYndyJDsa2trSjJUJSBnJMoikQiJxWK8nclk6MrnSVVC71Lv
+ pCohVx7MxrRdWtRbaYzKKnISq8rkRJXBiTJHZZXx8fGqHdYouTs6Orgc/MTE
+ hJKsra2tql9RhtAVZaOjozR8sA8tLCyoAYDx4XD4HwDNzc300fNQMBjkOnZk
+ tBhrIgN42x7QVoycppiupeKutgrllAtbWCi0J05qi1DQSqsUtq7/frxLao9K
+ lh6oN/L/I/MB+ADqnP4IMABJCQV+48xZ9wAAAABJRU5ErkJggg==
+ ====
--- /dev/null
+Copyright (C) 2007, 2008, 2009 Nokia Corporation. All rights reserved.
+
+Contact: Visa Smolander <visa.smolander@nokia.com>
+
+
+
--- /dev/null
+#!/bin/sh
+
+if test -x /usr/sbin/dsmetool; then
+ sudo /usr/bin/mafw.sh start mafw-gst-renderer -7
+fi
--- /dev/null
+/usr/lib/hildon-control-panel/libcpmpsubtitles.so
+/usr/share/applications/hildon-control-panel/cpmpsubtitles.desktop
+/usr/share/locale/*
\ No newline at end of file
--- /dev/null
+usr/lib/mafw-plugin
--- /dev/null
+@plugindir@/*.so
--- /dev/null
+#!/bin/sh
+
+#DEBHELPER#
+
+# purge old installed startup script
+if [ -f /etc/X11/Xsession.post/31mafw-gst-subtitles-renderer ]; then
+ rm -f /etc/X11/Xsession.post/31mafw-gst-subtitles-renderer
+fi
+
+/usr/bin/mafw.sh start mafw-gst-renderer -7
+
+exit 0
--- /dev/null
+#!/bin/sh
+
+#DEBHELPER#
+
+case "$1" in
+ remove)
+ # restore original mafw-gst-renderer on package removal
+ if [ -f /usr/lib/mafw-plugin/mafw-gst-renderer.so.removed ]; then
+ mv -f /usr/lib/mafw-plugin/mafw-gst-renderer.so.removed /usr/lib/mafw-plugin/mafw-gst-renderer.so
+ fi
+ ;;
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+ *)
+ exit 0
+esac
+
+/usr/bin/mafw.sh start mafw-gst-renderer -7
+
+exit 0
--- /dev/null
+#!/bin/sh
+
+#DEBHELPER#
+
+# create backup of original mafw-gst-renderer.so if it not exists
+if [ ! -f /usr/lib/mafw-plugin/mafw-gst-renderer.so.removed ]; then
+ /usr/bin/mafw.sh stop mafw-gst-renderer
+ mv -f /usr/lib/mafw-plugin/mafw-gst-renderer.so /usr/lib/mafw-plugin/mafw-gst-renderer.so.removed
+fi
+
+exit 0
--- /dev/null
+#!/bin/sh
+
+#DEBHELPER#
+
+/usr/bin/mafw.sh stop mafw-gst-renderer
+
+exit 0
--- /dev/null
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+
+ifneq (,$(findstring thumb,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -mthumb
+endif
+
+ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0 -ggdb3 -finstrument-functions
+endif
+
+ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+ INSTALL_PROGRAM += -s
+endif
+maybe_coverage := $(if $(filter lcov,$(DEB_BUILD_OPTIONS)),--enable-coverage,)
+
+configure-stamp:
+ dh_testdir
+ CFLAGS="$(CFLAGS)" ./autogen.sh \
+ --host=$(DEB_HOST_GNU_TYPE) \
+ --build=$(DEB_BUILD_GNU_TYPE) \
+ --disable-dependency-tracking \
+ --prefix=/usr \
+ $(maybe_coverage)
+ touch configure-stamp
+
+build: build-stamp
+build-stamp: configure-stamp
+ dh_testdir
+ $(MAKE)
+ifeq ($(findstring nocheck,$(DEB_BUILD_OPTIONS)),)
+ $(MAKE) check
+endif
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+ [ ! -f Makefile ] || $(MAKE) distclean
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+ $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
+
+binary-indep: build install
+
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs ChangeLog
+ dh_installdocs
+ dh_install --sourcedir=debian/tmp -v
+ dh_link
+ dh_strip --dbg-package=mafw-gst-subtitles-renderer
+ dh_compress
+ dh_fixperms
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+
+distcheck: build
+ dh_testdir
+ $(MAKE) distcheck
+
+vg:
+ dh_testdir
+ $(MAKE) -C "$(CURDIR)/tests" vg
+
+
+.PHONY: build clean binary-indep binary-arch binary install distcheck vg
--- /dev/null
+#
+# Makefile.am for MAFW gst renderer library.
+#
+# Author: Zeeshan Ali <zeeshan.ali@nokia.com>
+#
+# Copyright (C) 2007, 2008, 2009 Nokia. All rights reserved.
+
+plugin_LTLIBRARIES = mafw-gst-renderer.la
+
+BUILT_SOURCES = mafw-gst-renderer-marshal.c \
+ mafw-gst-renderer-marshal.h
+
+mafw_gst_renderer_la_SOURCES = $(BUILT_SOURCES) \
+ keypad.c keypad.h \
+ blanking.c blanking.h \
+ mafw-gst-renderer.c mafw-gst-renderer.h \
+ mafw-gst-renderer-utils.c mafw-gst-renderer-utils.h \
+ mafw-gst-renderer-worker.c mafw-gst-renderer-worker.h \
+ mafw-gst-renderer-worker-volume.c mafw-gst-renderer-worker-volume.h \
+ mafw-gst-renderer-state.c mafw-gst-renderer-state.h \
+ mafw-gst-renderer-state-playing.c mafw-gst-renderer-state-playing.h \
+ mafw-gst-renderer-state-paused.c mafw-gst-renderer-state-paused.h \
+ mafw-gst-renderer-state-stopped.c mafw-gst-renderer-state-stopped.h \
+ mafw-gst-renderer-state-transitioning.c mafw-gst-renderer-state-transitioning.h \
+ mafw-playlist-iterator.c mafw-playlist-iterator.h
+
+mafw_gst_renderer_la_CPPFLAGS = $(DEPS_CFLAGS) $(VOLUME_CFLAGS) \
+ -DPREFIX=\"$(prefix)\" $(_CFLAGS)
+mafw_gst_renderer_la_LDFLAGS = -avoid-version -module $(_LDFLAGS)
+mafw_gst_renderer_la_LIBADD = $(DEPS_LIBS) $(VOLUME_LIBS) \
+ -lgstinterfaces-0.10 -lgstpbutils-0.10
+
+if HAVE_GDKPIXBUF
+mafw_gst_renderer_la_SOURCES += gstscreenshot.c gstscreenshot.h
+mafw_gst_renderer_la_CPPFLAGS += $(GDKPIXBUF_CFLAGS)
+mafw_gst_renderer_la_LIBADD += $(GDKPIXBUF_LIBS)
+endif
+
+if HAVE_CONIC
+mafw_gst_renderer_la_CPPFLAGS += $(CONIC_CFLAGS)
+mafw_gst_renderer_la_LIBADD += $(CONIC_LIBS)
+endif
+
+mafw-gst-renderer-marshal.c: mafw-gst-renderer-marshal.list
+ ( \
+ echo '#include "mafw-gst-renderer-marshal.h"'; \
+ $(GLIB_GENMARSHAL) --prefix=mafw_gst_renderer_marshal --body $^ \
+ ) > $@
+
+mafw-gst-renderer-marshal.h: mafw-gst-renderer-marshal.list
+ $(GLIB_GENMARSHAL) --prefix=mafw_gst_renderer_marshal --header \
+ $^ > $@
+
+EXTRA_DIST = mafw-gst-renderer-marshal.list
+CLEANFILES = *.gcno *.gcda
+MAINTAINERCLEANFILES = Makefile.in *.loT
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <libosso.h>
+#include "blanking.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-blanking"
+
+/* In seconds */
+#define VIDEO_BLANKING_TIMER_INTERVAL 45
+
+static guint blanking_timeout_id = 0;
+static osso_context_t *osso_ctx = NULL;
+static gboolean can_control_blanking = TRUE;
+static gboolean is_blanking_prohibited = FALSE;
+
+static void remove_blanking_timeout(void)
+{
+ if (blanking_timeout_id) {
+ g_source_remove(blanking_timeout_id);
+ blanking_timeout_id = 0;
+ }
+}
+
+/*
+ * Re-enables screen blanking.
+ */
+void blanking_allow(void)
+{
+ is_blanking_prohibited = FALSE;
+ remove_blanking_timeout();
+}
+
+static gboolean no_blanking_timeout(void)
+{
+ /* Stop trying if it fails. */
+ return osso_display_blanking_pause(osso_ctx) == OSSO_OK;
+}
+
+/*
+ * Adds a timeout to periodically disable screen blanking.
+ */
+void blanking_prohibit(void)
+{
+ is_blanking_prohibited = TRUE;
+ if ((!osso_ctx) || (!can_control_blanking))
+ return;
+ osso_display_state_on(osso_ctx);
+ osso_display_blanking_pause(osso_ctx);
+ if (blanking_timeout_id == 0) {
+ blanking_timeout_id =
+ g_timeout_add_seconds(VIDEO_BLANKING_TIMER_INTERVAL,
+ (gpointer)no_blanking_timeout,
+ NULL);
+ }
+}
+
+void blanking_init(void)
+{
+ /* It's enough to initialize it once for a process. */
+ if (osso_ctx)
+ return;
+ osso_ctx = osso_initialize(PACKAGE, VERSION, 0, NULL);
+ if (!osso_ctx)
+ g_warning("osso_initialize failed, screen may go black");
+ is_blanking_prohibited = FALSE;
+ /* Default policy is to allow user to control blanking */
+ blanking_control(TRUE);
+}
+
+void blanking_deinit(void)
+{
+ if (!osso_ctx)
+ return;
+ blanking_control(FALSE);
+ osso_deinitialize(osso_ctx);
+ osso_ctx = NULL;
+}
+
+void blanking_control(gboolean activate)
+{
+ can_control_blanking = activate;
+ if (!can_control_blanking) {
+ remove_blanking_timeout();
+ } else {
+ /* Restore the last state */
+ if (is_blanking_prohibited) {
+ blanking_prohibit();
+ } else {
+ blanking_allow();
+ }
+ }
+}
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef BLANKING_H
+#define BLANKING_H
+
+G_BEGIN_DECLS
+
+void blanking_init(void);
+void blanking_deinit(void);
+void blanking_allow(void);
+void blanking_prohibit(void);
+void blanking_control(gboolean activate);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/* Small helper element for format conversion
+ * (c) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * Portion Copyright © 2009 Nokia Corporation and/or its
+ * subsidiary(-ies).* All rights reserved. *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <string.h>
+
+#include "gstscreenshot.h"
+
+typedef struct {
+ GstBuffer *result;
+ GstElement *src;
+ GstElement *sink;
+ GstElement *pipeline;
+ BvwFrameConvCb cb;
+ gpointer cb_data;
+} GstScreenshotData;
+
+/* GST_DEBUG_CATEGORY_EXTERN (_totem_gst_debug_cat); */
+/* #define GST_CAT_DEFAULT _totem_gst_debug_cat */
+
+static void feed_fakesrc(GstElement *src, GstBuffer *buf, GstPad *pad,
+ gpointer data)
+{
+ GstBuffer *in_buf = GST_BUFFER(data);
+
+ g_assert(GST_BUFFER_SIZE(buf) >= GST_BUFFER_SIZE(in_buf));
+ g_assert(!GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_READONLY));
+
+ gst_buffer_set_caps(buf, GST_BUFFER_CAPS(in_buf));
+
+ memcpy(GST_BUFFER_DATA(buf), GST_BUFFER_DATA(in_buf),
+ GST_BUFFER_SIZE(in_buf));
+
+ GST_BUFFER_SIZE(buf) = GST_BUFFER_SIZE(in_buf);
+
+ GST_DEBUG("feeding buffer %p, size %u, caps %" GST_PTR_FORMAT,
+ buf, GST_BUFFER_SIZE(buf), GST_BUFFER_CAPS(buf));
+
+ gst_buffer_unref(in_buf);
+}
+
+static void save_result(GstElement *sink, GstBuffer *buf, GstPad *pad,
+ gpointer data)
+{
+ GstScreenshotData *gsd = data;
+
+ gsd->result = gst_buffer_ref(buf);
+
+ GST_DEBUG("received converted buffer %p with caps %" GST_PTR_FORMAT,
+ gsd->result, GST_BUFFER_CAPS(gsd->result));
+}
+
+static gboolean create_element(const gchar *factory_name, GstElement **element,
+ GError **err)
+{
+ *element = gst_element_factory_make(factory_name, NULL);
+ if (*element)
+ return TRUE;
+
+ if (err && *err == NULL) {
+ *err = g_error_new(
+ GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN,
+ "cannot create element '%s' - please check your "
+ "GStreamer installation", factory_name);
+ }
+
+ return FALSE;
+}
+
+static gboolean finalize_process(GstScreenshotData *gsd)
+{
+ g_signal_handlers_disconnect_matched(gsd->sink, (GSignalMatchType)
+ G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ save_result, NULL);
+ g_signal_handlers_disconnect_matched(gsd->src, (GSignalMatchType)
+ G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ feed_fakesrc, NULL);
+ gst_element_set_state(gsd->pipeline, GST_STATE_NULL);
+
+ g_free(gsd);
+
+ return FALSE;
+}
+
+static gboolean async_bus_handler(GstBus *bus, GstMessage *msg,
+ gpointer data)
+{
+ GstScreenshotData *gsd = data;
+ gboolean keep_watch = TRUE;
+
+ switch (GST_MESSAGE_TYPE(msg)) {
+ case GST_MESSAGE_EOS: {
+ if (gsd->result != NULL) {
+ GST_DEBUG("conversion successful: result = %p",
+ gsd->result);
+ } else {
+ GST_WARNING("EOS but no result frame?!");
+ }
+ gsd->cb(gsd->result, gsd->cb_data);
+ keep_watch = finalize_process(gsd);
+ break;
+ }
+ case GST_MESSAGE_ERROR: {
+ gchar *dbg = NULL;
+ GError *error = NULL;
+
+ gst_message_parse_error(msg, &error, &dbg);
+ if (error != NULL) {
+ g_warning("Could not take screenshot: %s",
+ error->message);
+ GST_DEBUG("%s [debug: %s]", error->message,
+ GST_STR_NULL(dbg));
+ g_error_free(error);
+ } else {
+ g_warning("Could not take screenshot(and "
+ "NULL error!)");
+ }
+ g_free(dbg);
+ gsd->result = NULL;
+ gsd->cb(gsd->result, gsd->cb_data);
+ keep_watch = finalize_process(gsd);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return keep_watch;
+}
+
+/* takes ownership of the input buffer */
+gboolean bvw_frame_conv_convert(GstBuffer *buf, GstCaps *to_caps,
+ BvwFrameConvCb cb, gpointer cb_data)
+{
+ static GstElement *src = NULL, *sink = NULL, *pipeline = NULL,
+ *filter1 = NULL, *filter2 = NULL;
+ static GstBus *bus;
+ GError *error = NULL;
+ GstCaps *to_caps_no_par;
+ GstScreenshotData *gsd;
+
+ g_return_val_if_fail(GST_BUFFER_CAPS(buf) != NULL, FALSE);
+ g_return_val_if_fail(cb != NULL, FALSE);
+
+ if (pipeline == NULL) {
+ GstElement *csp, *vscale;
+
+ pipeline = gst_pipeline_new("screenshot-pipeline");
+ if(pipeline == NULL) {
+ g_warning("Could not take screenshot: "
+ "no pipeline (unknown error)");
+ return FALSE;
+ }
+
+ /* videoscale is here to correct for the
+ * pixel-aspect-ratio for us */
+ GST_DEBUG("creating elements");
+ if(!create_element("fakesrc", &src, &error) ||
+ !create_element("ffmpegcolorspace", &csp, &error) ||
+ !create_element("videoscale", &vscale, &error) ||
+ !create_element("capsfilter", &filter1, &error) ||
+ !create_element("capsfilter", &filter2, &error) ||
+ !create_element("fakesink", &sink, &error)) {
+ g_warning("Could not take screenshot: %s",
+ error->message);
+ g_error_free(error);
+ return FALSE;
+ }
+
+ GST_DEBUG("adding elements");
+ gst_bin_add_many(GST_BIN(pipeline), src, csp, filter1, vscale,
+ filter2, sink, NULL);
+
+ g_object_set(sink, "preroll-queue-len", 1,
+ "signal-handoffs", TRUE, NULL);
+
+ /* set to 'fixed' sizetype */
+ g_object_set(src, "sizetype", 2, "num-buffers", 1,
+ "signal-handoffs", TRUE, NULL);
+
+ /* FIXME: linking is still way too expensive, profile
+ * this properly */
+ GST_DEBUG("linking src->csp");
+ if(!gst_element_link_pads(src, "src", csp, "sink"))
+ return FALSE;
+
+ GST_DEBUG("linking csp->filter1");
+ if(!gst_element_link_pads(csp, "src", filter1, "sink"))
+ return FALSE;
+
+ GST_DEBUG("linking filter1->vscale");
+ if(!gst_element_link_pads(filter1, "src", vscale, "sink"))
+ return FALSE;
+
+ GST_DEBUG("linking vscale->capsfilter");
+ if(!gst_element_link_pads(vscale, "src", filter2, "sink"))
+ return FALSE;
+
+ GST_DEBUG("linking capsfilter->sink");
+ if(!gst_element_link_pads(filter2, "src", sink, "sink"))
+ return FALSE;
+
+ bus = gst_element_get_bus(pipeline);
+ }
+
+ /* adding this superfluous capsfilter makes linking cheaper */
+ to_caps_no_par = gst_caps_copy(to_caps);
+ gst_structure_remove_field(gst_caps_get_structure(to_caps_no_par, 0),
+ "pixel-aspect-ratio");
+ g_object_set(filter1, "caps", to_caps_no_par, NULL);
+ gst_caps_unref(to_caps_no_par);
+
+ g_object_set(filter2, "caps", to_caps, NULL);
+ gst_caps_unref(to_caps);
+
+ gsd = g_new0(GstScreenshotData, 1);
+
+ gsd->src = src;
+ gsd->sink = sink;
+ gsd->pipeline = pipeline;
+ gsd->cb = cb;
+ gsd->cb_data = cb_data;
+
+ g_signal_connect(sink, "handoff", G_CALLBACK(save_result), gsd);
+
+ g_signal_connect(src, "handoff", G_CALLBACK(feed_fakesrc), buf);
+
+ gst_bus_add_watch(bus, async_bus_handler, gsd);
+
+ /* set to 'fixed' sizetype */
+ g_object_set(src, "sizemax", GST_BUFFER_SIZE(buf), NULL);
+
+ GST_DEBUG("running conversion pipeline");
+ gst_element_set_state(pipeline, GST_STATE_PLAYING);
+
+ return TRUE;
+}
--- /dev/null
+/* Small helper element for format conversion
+ * (c) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * Portion Copyright © 2009 Nokia Corporation and/or its
+ * subsidiary(-ies).* All rights reserved. *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __BVW_FRAME_CONV_H__
+#define __BVW_FRAME_CONV_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+typedef void (*BvwFrameConvCb)(GstBuffer *result, gpointer user_data);
+
+gboolean bvw_frame_conv_convert (GstBuffer *buf, GstCaps *to,
+ BvwFrameConvCb cb, gpointer cb_data);
+
+G_END_DECLS
+
+#endif /* __BVW_FRAME_CONV_H__ */
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <glib.h>
+#include <mce/dbus-names.h>
+#include <dbus/dbus.h>
+#include "keypad.h"
+
+
+#define KEYPAD_TIMER_INTERVAL 50
+
+static guint toutid;
+
+void keypadlocking_allow(void)
+{
+ if (toutid)
+ {
+ g_source_remove(toutid);
+ toutid = 0;
+ }
+}
+
+static gboolean no_keylock_timeout(gpointer udata)
+{
+ static DBusMessage *msg = NULL;
+ static DBusConnection *sysbus = NULL;
+
+ if (!sysbus)
+ {
+ DBusError err;
+
+ dbus_error_init(&err);
+ sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+ g_assert(sysbus);
+ g_assert(!dbus_error_is_set(&err));
+ }
+ if (!msg)
+ {
+ msg = dbus_message_new_method_call(MCE_SERVICE,
+ MCE_REQUEST_PATH, MCE_REQUEST_IF,
+ MCE_PREVENT_KEYPAD_OFF_REQ);
+ g_assert(msg);
+ }
+ g_assert(dbus_connection_send(sysbus, msg,NULL));
+ dbus_connection_flush(sysbus);
+ return TRUE;
+}
+
+void keypadlocking_prohibit(void)
+{
+ if (!toutid)
+ {
+ toutid = g_timeout_add_seconds(KEYPAD_TIMER_INTERVAL,
+ no_keylock_timeout,
+ NULL);
+ no_keylock_timeout(NULL);
+ }
+}
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef KEYPAD_H
+#define KEYPAD_H
+
+G_BEGIN_DECLS
+
+void keypadlocking_prohibit(void);
+void keypadlocking_allow(void);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+#include "mafw-gst-renderer-marshal.h"
+
+#include <glib-object.h>
+
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v) g_value_get_char (v)
+#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v) g_value_get_int (v)
+#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
+#define g_marshal_value_peek_long(v) g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
+#define g_marshal_value_peek_float(v) g_value_get_float (v)
+#define g_marshal_value_peek_double(v) g_value_get_double (v)
+#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v) g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v) g_value_get_object (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ * Do not access GValues directly in your code. Instead, use the
+ * g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
+#define g_marshal_value_peek_char(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v) (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v) (v)->data[0].v_float
+#define g_marshal_value_peek_double(v) (v)->data[0].v_double
+#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* VOID:BOOLEAN,UINT,INT,STRING (mafw-gst-renderer-marshal.list:2) */
+void
+mafw_gst_renderer_marshal_VOID__BOOLEAN_UINT_INT_STRING (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__BOOLEAN_UINT_INT_STRING) (gpointer data1,
+ gboolean arg_1,
+ guint arg_2,
+ gint arg_3,
+ gpointer arg_4,
+ gpointer data2);
+ register GMarshalFunc_VOID__BOOLEAN_UINT_INT_STRING callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 5);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__BOOLEAN_UINT_INT_STRING) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_boolean (param_values + 1),
+ g_marshal_value_peek_uint (param_values + 2),
+ g_marshal_value_peek_int (param_values + 3),
+ g_marshal_value_peek_string (param_values + 4),
+ data2);
+}
+
--- /dev/null
+
+#ifndef __mafw_gst_renderer_marshal_MARSHAL_H__
+#define __mafw_gst_renderer_marshal_MARSHAL_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* VOID:BOOLEAN,UINT,INT,STRING (mafw-gst-renderer-marshal.list:2) */
+extern void mafw_gst_renderer_marshal_VOID__BOOLEAN_UINT_INT_STRING (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+G_END_DECLS
+
+#endif /* __mafw_gst_renderer_marshal_MARSHAL_H__ */
+
--- /dev/null
+# MafwPlaylistIterator::playlist-changed(clip_changed, domain, code, message)
+VOID: BOOLEAN, UINT, INT, STRING
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "mafw-gst-renderer-state-paused.h"
+#include "mafw-gst-renderer-utils.h"
+#include <libmafw/mafw.h>
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-state-paused"
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+static void _do_play(MafwGstRendererState *self, GError **error);
+static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
+ GError **error);
+static void _do_stop(MafwGstRendererState *self, GError **error);
+static void _do_resume(MafwGstRendererState *self, GError **error);
+static void _do_set_position(MafwGstRendererState *self,
+ MafwRendererSeekMode mode, gint seconds,
+ GError **error);
+static void _do_get_position(MafwGstRendererState *self,
+ gint *seconds,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+static void _do_next(MafwGstRendererState *self, GError **error);
+static void _do_previous(MafwGstRendererState *self, GError **error);
+static void _do_goto_index(MafwGstRendererState *self, guint index,
+ GError **error);
+/*----------------------------------------------------------------------------
+ Notification metatada
+ ----------------------------------------------------------------------------*/
+
+static void _notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Notification worker
+ ----------------------------------------------------------------------------*/
+
+static void _notify_play(MafwGstRendererState *self, GError **error);
+static void _notify_seek(MafwGstRendererState *self, GError **error);
+static void _notify_buffer_status(MafwGstRendererState *self, gdouble percent,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Playlist editing signals
+ ----------------------------------------------------------------------------*/
+
+static void _playlist_contents_changed(MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Property methods
+ ----------------------------------------------------------------------------*/
+
+static GValue* _get_property_value(MafwGstRendererState *self,
+ const gchar *name);
+
+/*----------------------------------------------------------------------------
+ Memory card event handlers
+ ----------------------------------------------------------------------------*/
+
+static void _handle_pre_unmount(MafwGstRendererState *self,
+ const gchar *mount_point);
+
+/*----------------------------------------------------------------------------
+ GObject initialization
+ ----------------------------------------------------------------------------*/
+
+G_DEFINE_TYPE(MafwGstRendererStatePaused, mafw_gst_renderer_state_paused,
+ MAFW_TYPE_GST_RENDERER_STATE);
+
+static void mafw_gst_renderer_state_paused_init(MafwGstRendererStatePaused *self)
+{
+}
+
+static void mafw_gst_renderer_state_paused_class_init(
+ MafwGstRendererStatePausedClass *klass)
+{
+ MafwGstRendererStateClass *state_class;
+
+ state_class = MAFW_GST_RENDERER_STATE_CLASS(klass);
+ g_return_if_fail(state_class != NULL);
+
+ state_class->name = g_strdup("Paused");
+
+ /* Playback */
+
+ state_class->play = _do_play;
+ state_class->play_object = _do_play_object;
+ state_class->stop = _do_stop;
+ state_class->resume = _do_resume;
+ state_class->set_position = _do_set_position;
+ state_class->get_position = _do_get_position;
+
+ /* Playlist */
+
+ state_class->next = _do_next;
+ state_class->previous = _do_previous;
+ state_class->goto_index = _do_goto_index;
+
+ /* Notification metadata */
+
+ state_class->notify_metadata = _notify_metadata;
+
+ /* Notification worker */
+
+ state_class->notify_play = _notify_play;
+ /* state_class->notify_pause is not allowed */
+ state_class->notify_seek = _notify_seek;
+ state_class->notify_buffer_status = _notify_buffer_status;
+
+ /* Playlist editing signals */
+
+ state_class->playlist_contents_changed =
+ _playlist_contents_changed;
+
+ /* Property methods */
+
+ state_class->get_property_value = _get_property_value;
+
+ /* Memory card event handlers */
+
+ state_class->handle_pre_unmount = _handle_pre_unmount;
+}
+
+GObject *mafw_gst_renderer_state_paused_new(MafwGstRenderer *renderer)
+{
+ MafwGstRendererState *state;
+
+ state = MAFW_GST_RENDERER_STATE(
+ g_object_new(MAFW_TYPE_GST_RENDERER_STATE_PAUSED, NULL));
+ state->renderer = renderer;
+
+ return G_OBJECT(state);
+}
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+static void _do_play(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+ mafw_gst_renderer_state_do_play(self, error);
+}
+
+static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
+ GError **error)
+{
+ MafwGstRendererPlaybackMode cur_mode, prev_mode;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+
+ self->renderer->worker->stay_paused = FALSE;
+ prev_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+ mafw_gst_renderer_state_do_play_object(self, object_id, error);
+ cur_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+
+ /* If this happens it means that we interrupted playlist playback
+ so let's resume it when play_object is finished */
+ if (cur_mode != prev_mode) {
+ self->renderer->resume_playlist = TRUE;
+ }
+}
+
+static void _do_stop(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+
+ self->renderer->worker->stay_paused = FALSE;
+ /* Stop playback */
+ mafw_gst_renderer_state_do_stop(self, error);
+}
+
+static void _do_resume(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+
+ MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+ self->renderer->worker->stay_paused = FALSE;
+ mafw_gst_renderer_worker_resume(renderer->worker);
+
+ /* Transition will be done after receiving notify_play */
+}
+
+static void _do_set_position(MafwGstRendererState *self,
+ MafwRendererSeekMode mode, gint seconds,
+ GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+ self->renderer->worker->stay_paused = TRUE;
+ mafw_gst_renderer_state_do_set_position(self, mode, seconds, error);
+}
+
+static void _do_get_position(MafwGstRendererState *self,
+ gint *seconds,
+ GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+ mafw_gst_renderer_state_do_get_position(self, seconds, error);
+}
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+static void _do_next(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+ self->renderer->worker->stay_paused = TRUE;
+ mafw_gst_renderer_state_do_next(self, error);
+}
+
+static void _do_previous(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+ self->renderer->worker->stay_paused = TRUE;
+ mafw_gst_renderer_state_do_prev(self, error);
+}
+
+static void _do_goto_index(MafwGstRendererState *self, guint index,
+ GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+ self->renderer->worker->stay_paused = TRUE;
+ mafw_gst_renderer_state_do_goto_index(self, index, error);
+}
+
+
+/*----------------------------------------------------------------------------
+ Notification metatada
+ ----------------------------------------------------------------------------*/
+
+static void _notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error)
+{
+ g_debug("running _notify_metadata...");
+ /* Kindly Ignore this notification:
+ probably a delayed (now useless) metadata resolution */
+}
+
+
+/*----------------------------------------------------------------------------
+ Notification worker
+ ----------------------------------------------------------------------------*/
+
+static void _notify_play(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+
+ MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ /* Change status to play */
+ mafw_gst_renderer_set_state(renderer, Playing);
+}
+
+static void _notify_seek(MafwGstRendererState *self, GError **error)
+{
+ mafw_gst_renderer_state_do_notify_seek(self, error);
+}
+
+static void _notify_buffer_status(MafwGstRendererState *self, gdouble percent,
+ GError **error)
+{
+ mafw_gst_renderer_state_do_notify_buffer_status (self, percent, error);
+}
+
+/*----------------------------------------------------------------------------
+ Playlist editing signals
+ ----------------------------------------------------------------------------*/
+
+static void _playlist_contents_changed(MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error)
+{
+ MafwGstRendererPlaybackMode mode;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self));
+
+ /* Play the new index only if we are not in standalone mode.
+ Otherwise, when play_object finishes the new item will be
+ played if that's been suggested with renderer->resume_playlist */
+ mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+ if (clip_changed && mode == MAFW_GST_RENDERER_MODE_PLAYLIST) {
+ self->renderer->worker->stay_paused = TRUE;
+ mafw_gst_renderer_state_do_play(self, error);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Property methods
+ ----------------------------------------------------------------------------*/
+
+GValue* _get_property_value(MafwGstRendererState *self, const gchar *name)
+{
+ GValue *value = NULL;
+
+ g_return_val_if_fail(MAFW_IS_GST_RENDERER_STATE_PAUSED(self), value);
+
+ if (!g_strcmp0(name, MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS)) {
+ gboolean is_seekable =
+ mafw_gst_renderer_worker_get_seekable(
+ self->renderer->worker);
+
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_STRING);
+ if (is_seekable) {
+ g_value_set_string(value, "seek");
+ } else {
+ g_value_set_string(value, "");
+ }
+ }
+
+ return value;
+}
+
+/*----------------------------------------------------------------------------
+ Memory card event handlers
+ ----------------------------------------------------------------------------*/
+
+static void _handle_pre_unmount(MafwGstRendererState *self,
+ const gchar *mount_point)
+{
+ gchar *mount_uri;
+
+ /* If not playing anything, bail out */
+ if (!self->renderer->media->uri) {
+ return;
+ }
+
+ /* Check if mount point is URI or path, we need URI */
+ if (!g_str_has_prefix(mount_point, "file://")) {
+ mount_uri = g_filename_to_uri(mount_point, NULL, NULL);
+ } else {
+ mount_uri = g_strdup(mount_point);
+ }
+
+ /* Stop if playing from unmounted location */
+ if (g_str_has_prefix(self->renderer->media->uri, mount_uri)) {
+ g_debug("PAUSED-STATE: stopping to mount card");
+ mafw_gst_renderer_stop(MAFW_RENDERER(self->renderer),
+ NULL,
+ NULL);
+ }
+
+ g_free(mount_uri);
+}
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef MAFW_GST_RENDERER_STATE_PAUSED_H
+#define MAFW_GST_RENDERER_STATE_PAUSED_H
+
+
+#include "mafw-gst-renderer.h"
+#include "mafw-gst-renderer-state.h"
+
+G_BEGIN_DECLS
+
+/*----------------------------------------------------------------------------
+ GObject type conversion macros
+ ----------------------------------------------------------------------------*/
+
+#define MAFW_TYPE_GST_RENDERER_STATE_PAUSED \
+ (mafw_gst_renderer_state_paused_get_type())
+#define MAFW_GST_RENDERER_STATE_PAUSED(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_GST_RENDERER_STATE_PAUSED, \
+ MafwGstRendererStatePaused))
+#define MAFW_IS_GST_RENDERER_STATE_PAUSED(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_GST_RENDERER_STATE_PAUSED))
+#define MAFW_GST_RENDERER_STATE_PAUSED_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_GST_RENDERER_STATE_PAUSED, \
+ MafwGstRendererStatePaused))
+#define MAFW_GST_RENDERER_STATE_PAUSED_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_GST_RENDERER_STATE_PAUSED, \
+ MafwGstRendererStatePausedClass))
+#define MAFW_IS_GST_RENDERER_STATE_PAUSED_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_GST_RENDERER_STATE_PAUSED))
+
+/*----------------------------------------------------------------------------
+ Type definitions
+ ----------------------------------------------------------------------------*/
+
+
+typedef struct _MafwGstRendererStatePaused MafwGstRendererStatePaused;
+typedef struct _MafwGstRendererStatePausedClass MafwGstRendererStatePausedClass;
+
+struct _MafwGstRendererStatePausedClass {
+ MafwGstRendererStateClass parent_class;
+};
+
+struct _MafwGstRendererStatePaused {
+ MafwGstRendererState parent;
+};
+
+GType mafw_gst_renderer_state_paused_get_type(void);
+
+GObject *mafw_gst_renderer_state_paused_new(MafwGstRenderer *renderer);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "mafw-gst-renderer-state-playing.h"
+#include "mafw-gst-renderer-utils.h"
+#include <libmafw/mafw.h>
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-state-playing"
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+static void _do_play(MafwGstRendererState *self, GError **error);
+static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
+ GError **error);
+static void _do_stop(MafwGstRendererState *self, GError **error);
+static void _do_pause(MafwGstRendererState *self, GError **error);
+static void _do_set_position(MafwGstRendererState *self,
+ MafwRendererSeekMode mode, gint seconds,
+ GError **error);
+static void _do_get_position(MafwGstRendererState *self,
+ gint *seconds,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+static void _do_next(MafwGstRendererState *self, GError **error);
+static void _do_previous(MafwGstRendererState *self, GError **error);
+static void _do_goto_index(MafwGstRendererState *self, guint index,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Notification metatada
+ ----------------------------------------------------------------------------*/
+
+static void _notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Notification worker
+ ----------------------------------------------------------------------------*/
+
+static void _notify_play(MafwGstRendererState *self, GError **error);
+static void _notify_pause(MafwGstRendererState *self, GError **error);
+static void _notify_seek(MafwGstRendererState *self, GError **error);
+static void _notify_buffer_status(MafwGstRendererState *self, gdouble percent,
+ GError **error);
+static void _notify_eos(MafwGstRendererState *self, GError **error);
+
+/*----------------------------------------------------------------------------
+ Playlist editing signals
+ ----------------------------------------------------------------------------*/
+
+static void _playlist_contents_changed(MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Property methods
+ ----------------------------------------------------------------------------*/
+
+static GValue* _get_property_value(MafwGstRendererState *self,
+ const gchar *name);
+
+/*----------------------------------------------------------------------------
+ Memory card event handlers
+ ----------------------------------------------------------------------------*/
+
+static void _handle_pre_unmount(MafwGstRendererState *self,
+ const gchar *mount_point);
+
+/*----------------------------------------------------------------------------
+ GObject initialization
+ ----------------------------------------------------------------------------*/
+
+G_DEFINE_TYPE(MafwGstRendererStatePlaying, mafw_gst_renderer_state_playing,
+ MAFW_TYPE_GST_RENDERER_STATE);
+
+static void mafw_gst_renderer_state_playing_init(MafwGstRendererStatePlaying *self)
+{
+}
+
+static void mafw_gst_renderer_state_playing_class_init(
+ MafwGstRendererStatePlayingClass *klass)
+{
+ MafwGstRendererStateClass *state_class;
+
+ state_class = MAFW_GST_RENDERER_STATE_CLASS(klass);
+ g_return_if_fail(state_class != NULL);
+
+ state_class->name = g_strdup("Playing");
+
+ /* Playback */
+
+ state_class->play = _do_play;
+ state_class->play_object = _do_play_object;
+ state_class->stop = _do_stop;
+ state_class->pause = _do_pause;
+ /* state_class->resume is not allowed */
+ state_class->set_position = _do_set_position;
+ state_class->get_position = _do_get_position;
+
+ /* Playlist */
+
+ state_class->next = _do_next;
+ state_class->previous = _do_previous;
+ state_class->goto_index = _do_goto_index;
+
+ /* Notification metadata */
+
+ state_class->notify_metadata = _notify_metadata;
+
+ /* Notification worker */
+
+ state_class->notify_play = _notify_play;
+ state_class->notify_pause = _notify_pause;
+ state_class->notify_seek = _notify_seek;
+ state_class->notify_buffer_status = _notify_buffer_status;
+ state_class->notify_eos = _notify_eos;
+
+ /* Playlist editing signals */
+
+ state_class->playlist_contents_changed =
+ _playlist_contents_changed;
+
+ /* Property methods */
+
+ state_class->get_property_value = _get_property_value;
+
+ /* Memory card event handlers */
+
+ state_class->handle_pre_unmount = _handle_pre_unmount;
+}
+
+GObject *mafw_gst_renderer_state_playing_new(MafwGstRenderer *renderer)
+{
+ MafwGstRendererState *state;
+
+ state = MAFW_GST_RENDERER_STATE(
+ g_object_new(MAFW_TYPE_GST_RENDERER_STATE_PLAYING, NULL));
+ state->renderer = renderer;
+
+ return G_OBJECT(state);
+}
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+static void _do_play(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+ mafw_gst_renderer_state_do_play(self, error);
+}
+
+static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
+ GError **error)
+{
+ MafwGstRendererPlaybackMode cur_mode, prev_mode;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+
+ prev_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+ mafw_gst_renderer_state_do_play_object(self, object_id, error);
+ cur_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+
+ /* If this happens it means that we interrupted playlist playback
+ so let's resume it when play_object is finished */
+ if (cur_mode != prev_mode) {
+ self->renderer->resume_playlist = TRUE;
+ }
+}
+
+static void _do_stop(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+
+ /* Stop playback */
+ mafw_gst_renderer_state_do_stop(self, error);
+}
+
+static void _do_pause(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+
+ MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+ mafw_gst_renderer_worker_pause(renderer->worker);
+
+ /* Transition will be done when receiving pause
+ * notification */
+}
+
+static void _do_set_position(MafwGstRendererState *self,
+ MafwRendererSeekMode mode, gint seconds,
+ GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+ mafw_gst_renderer_state_do_set_position(self, mode, seconds, error);
+}
+
+static void _do_get_position(MafwGstRendererState *self,
+ gint *seconds,
+ GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+ mafw_gst_renderer_state_do_get_position(self, seconds, error);
+}
+
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+static void _do_next(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+ mafw_gst_renderer_state_do_next(self, error);
+}
+
+static void _do_previous(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+ mafw_gst_renderer_state_do_prev(self, error);
+}
+
+static void _do_goto_index(MafwGstRendererState *self, guint index,
+ GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+ mafw_gst_renderer_state_do_goto_index(self, index, error);
+}
+
+
+/*----------------------------------------------------------------------------
+ Notification metatada
+ ----------------------------------------------------------------------------*/
+
+static void _notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error)
+{
+ g_debug("running _notify_metadata...");
+ /* Kindly Ignore this notification:
+ probably a delayed (now useless) metadata resolution */
+}
+
+
+/*----------------------------------------------------------------------------
+ Notification worker
+ ----------------------------------------------------------------------------*/
+
+static void _notify_play(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+ /* Kindly ignore this notification: it's received when seeking
+ * in a stream */
+}
+
+static void _notify_pause(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+
+ MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ /* Change status to pause */
+ mafw_gst_renderer_set_state(renderer, Paused);
+}
+
+static void _notify_seek(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+ mafw_gst_renderer_state_do_notify_seek(self, error);
+}
+
+static void _notify_buffer_status(MafwGstRendererState *self, gdouble percent,
+ GError **error)
+{
+ mafw_gst_renderer_state_do_notify_buffer_status (self, percent, error);
+}
+
+static void _notify_eos(MafwGstRendererState *self, GError **error)
+{
+ MafwGstRenderer *renderer;
+ MafwGstRendererMovementResult move_type;
+ MafwGstRendererPlaybackMode mode;
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ /* Update playcount */
+ if (renderer->update_playcount_id > 0) {
+ g_source_remove(renderer->update_playcount_id);
+ mafw_gst_renderer_update_stats(renderer);
+ }
+
+ /* Notice: playback has already stopped, so calling
+ * mafw_gst_renderer_stop or mafw_gst_renderer_state_stop
+ * here is an error.
+ * To set the renderer state to Stopped use this instead:
+ * mafw_gst_renderer_set_state(self->renderer, Stopped);
+ */
+
+ /* If we are not in playlist mode, switch to it,
+ otherwise move to the next in the playlist */
+ mode = mafw_gst_renderer_get_playback_mode(renderer);
+ if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
+ mafw_gst_renderer_worker_stop(self->renderer->worker);
+ mafw_gst_renderer_set_state(self->renderer, Stopped);
+ mafw_gst_renderer_set_playback_mode(
+ renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
+ mafw_gst_renderer_set_media_playlist(renderer);
+
+ /* Do we have to resume playlist playback? */
+ if (renderer->resume_playlist) {
+ mafw_gst_renderer_state_play(self, error);
+ }
+ }
+ else
+ {
+ gboolean is_stream = uri_is_stream(self->renderer->worker->media.location);
+ if (is_stream
+ && self->renderer->error_policy == MAFW_RENDERER_ERROR_POLICY_STOP
+ && self->renderer->worker->media.length_nanos == -1
+ && self->renderer->worker->media.seekable == SEEKABILITY_NO_SEEKABLE
+ && self->renderer->worker->media.has_visual_content == FALSE)
+ {
+ /* Endless Radio stream. Stream has no length, it is not seekable or it is not video. */
+ mafw_gst_renderer_worker_stop(self->renderer->worker);
+ mafw_gst_renderer_set_state(self->renderer, Stopped);
+ g_signal_emit_by_name(MAFW_EXTENSION(self->renderer), "error",
+ MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_STREAM_DISCONNECTED,
+ "EOS FOR ENDLESS STREAM");
+ }
+ else
+ {
+ /* Move to next in playlist */
+ move_type =
+ mafw_gst_renderer_move(renderer,
+ MAFW_GST_RENDERER_MOVE_TYPE_NEXT,
+ 0, error);
+
+ switch (move_type)
+ {
+ case MAFW_GST_RENDERER_MOVE_RESULT_OK:
+ mafw_gst_renderer_state_play(self, error);
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
+ case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
+ mafw_gst_renderer_worker_stop(self->renderer->worker);
+ mafw_gst_renderer_set_state(self->renderer, Stopped);
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
+ break;
+ default:
+ g_critical("Movement not controlled");
+ }
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Playlist editing signals
+ ----------------------------------------------------------------------------*/
+
+static void _playlist_contents_changed(MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error)
+{
+ MafwGstRendererPlaybackMode mode;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self));
+
+ /* Play the new index only if we are not in standalone mode.
+ Otherwise, when play_object finishes the new item will be
+ played if that's been suggested with renderer->resume_playlist */
+ mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+ if (clip_changed && mode == MAFW_GST_RENDERER_MODE_PLAYLIST) {
+ mafw_gst_renderer_state_do_play(self, error);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Property methods
+ ----------------------------------------------------------------------------*/
+
+GValue* _get_property_value(MafwGstRendererState *self, const gchar *name)
+{
+ GValue *value = NULL;
+
+ g_return_val_if_fail(MAFW_IS_GST_RENDERER_STATE_PLAYING(self), value);
+
+ if (!g_strcmp0(name, MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS)) {
+ gboolean is_seekable =
+ mafw_gst_renderer_worker_get_seekable(
+ self->renderer->worker);
+
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_STRING);
+ if (is_seekable) {
+ g_value_set_string(value, "seek");
+ } else {
+ g_value_set_string(value, "");
+ }
+ }
+
+ return value;
+}
+
+/*----------------------------------------------------------------------------
+ Memory card event handlers
+ ----------------------------------------------------------------------------*/
+
+static void _handle_pre_unmount(MafwGstRendererState *self,
+ const gchar *mount_point)
+{
+ gchar *mount_uri;
+
+ /* If not playing anything, bail out */
+ if (!self->renderer->media->uri) {
+ return;
+ }
+
+ /* Check if mount point is URI or path, we need URI */
+ if (!g_str_has_prefix(mount_point, "file://")) {
+ mount_uri = g_filename_to_uri(mount_point, NULL, NULL);
+ } else {
+ mount_uri = g_strdup(mount_point);
+ }
+
+ /* Stop if playing from unmounted location */
+ if (g_str_has_prefix(self->renderer->media->uri, mount_uri)) {
+ mafw_gst_renderer_stop(MAFW_RENDERER(self->renderer),
+ NULL,
+ NULL);
+ }
+
+ g_free(mount_uri);
+}
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef MAFW_GST_RENDERER_STATE_PLAYING_H
+#define MAFW_GST_RENDERER_STATE_PLAYING_H
+
+
+#include "mafw-gst-renderer.h"
+#include "mafw-gst-renderer-state.h"
+
+G_BEGIN_DECLS
+
+/*----------------------------------------------------------------------------
+ GObject type conversion macros
+ ----------------------------------------------------------------------------*/
+
+#define MAFW_TYPE_GST_RENDERER_STATE_PLAYING \
+ (mafw_gst_renderer_state_playing_get_type())
+#define MAFW_GST_RENDERER_STATE_PLAYING(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_GST_RENDERER_STATE_PLAYING, \
+ MafwGstRendererStatePlaying))
+#define MAFW_IS_GST_RENDERER_STATE_PLAYING(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_GST_RENDERER_STATE_PLAYING))
+#define MAFW_GST_RENDERER_STATE_PLAYING_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_GST_RENDERER_STATE_PLAYING, \
+ MafwGstRendererStatePlaying))
+#define MAFW_GST_RENDERER_STATE_PLAYING_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_GST_RENDERER_STATE_PLAYING, \
+ MafwGstRendererStatePlayingClass))
+#define MAFW_IS_GST_RENDERER_STATE_PLAYING_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_GST_RENDERER_STATE_PLAYING))
+
+/*----------------------------------------------------------------------------
+ Type definitions
+ ----------------------------------------------------------------------------*/
+
+
+typedef struct _MafwGstRendererStatePlaying MafwGstRendererStatePlaying;
+typedef struct _MafwGstRendererStatePlayingClass MafwGstRendererStatePlayingClass;
+
+struct _MafwGstRendererStatePlayingClass {
+ MafwGstRendererStateClass parent_class;
+};
+
+struct _MafwGstRendererStatePlaying {
+ MafwGstRendererState parent;
+};
+
+GType mafw_gst_renderer_state_playing_get_type(void);
+
+GObject *mafw_gst_renderer_state_playing_new(MafwGstRenderer *renderer);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <libmafw/mafw-errors.h>
+#include "mafw-gst-renderer-state-stopped.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-state-stopped"
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+static void _do_play(MafwGstRendererState *self, GError **error);
+static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
+ GError **error);
+static void _do_stop(MafwGstRendererState *self, GError **error);
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+static void _do_next(MafwGstRendererState *self, GError **error);
+static void _do_previous(MafwGstRendererState *self, GError **error);
+static void _do_goto_index(MafwGstRendererState *self, guint index,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Notification metatada
+ ----------------------------------------------------------------------------*/
+
+static void _notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Playlist editing signals
+ ----------------------------------------------------------------------------*/
+
+static void _playlist_contents_changed(MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Property methods
+ ----------------------------------------------------------------------------*/
+
+static GValue* _get_property_value(MafwGstRendererState *self,
+ const gchar *name);
+
+/*----------------------------------------------------------------------------
+ GObject initialization
+ ----------------------------------------------------------------------------*/
+
+G_DEFINE_TYPE(MafwGstRendererStateStopped, mafw_gst_renderer_state_stopped,
+ MAFW_TYPE_GST_RENDERER_STATE);
+
+static void mafw_gst_renderer_state_stopped_init(MafwGstRendererStateStopped *self)
+{
+}
+
+static void mafw_gst_renderer_state_stopped_class_init(
+ MafwGstRendererStateStoppedClass *klass)
+{
+ MafwGstRendererStateClass *state_klass;
+
+ state_klass = MAFW_GST_RENDERER_STATE_CLASS(klass);
+ g_return_if_fail(state_klass != NULL);
+
+ state_klass->name = g_strdup("Stopped");
+
+ /* Playback */
+
+ state_klass->play = _do_play;
+ state_klass->play_object = _do_play_object;
+ state_klass->stop = _do_stop;
+
+ /* Playlist */
+
+ state_klass->next = _do_next;
+ state_klass->previous = _do_previous;
+ state_klass->goto_index = _do_goto_index;
+
+ /* Metadata */
+
+ state_klass->notify_metadata = _notify_metadata;
+
+ /* Playlist editing signals */
+
+ state_klass->playlist_contents_changed =
+ _playlist_contents_changed;
+
+ /* Property methods */
+
+ state_klass->get_property_value = _get_property_value;
+}
+
+GObject *mafw_gst_renderer_state_stopped_new(MafwGstRenderer *renderer)
+{
+ MafwGstRendererState *state;
+
+ state = MAFW_GST_RENDERER_STATE(
+ g_object_new(MAFW_TYPE_GST_RENDERER_STATE_STOPPED, NULL));
+ state->renderer = renderer;
+
+ return G_OBJECT(state);
+}
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+static void _do_play(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
+ mafw_gst_renderer_state_do_play(self, error);
+}
+
+static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
+ GError **error)
+{
+ MafwGstRendererPlaybackMode cur_mode, prev_mode;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
+
+ prev_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+ mafw_gst_renderer_state_do_play_object(self, object_id, error);
+ cur_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+
+ /* If this happens it means that we interrupted playlist mode
+ but we did so in Stopped state, so when play_object finishes
+ we want to stay Stopped */
+ if (cur_mode != prev_mode) {
+ self->renderer->resume_playlist = FALSE;
+ }
+}
+
+static void _do_stop(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
+ /* We are already in Stopped state, so do nothing */
+}
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+static void _do_next(MafwGstRendererState *self, GError **error)
+{
+ MafwGstRenderer *renderer = NULL;
+ MafwGstRendererMovementResult value = MAFW_GST_RENDERER_MOVE_RESULT_OK;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ value = mafw_gst_renderer_move(renderer,
+ MAFW_GST_RENDERER_MOVE_TYPE_NEXT,
+ 0, error);
+
+ switch (value) {
+ case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
+ case MAFW_GST_RENDERER_MOVE_RESULT_OK:
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
+ g_set_error (error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_NO_MEDIA,
+ "There is no playlist or media to play");
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
+ mafw_playlist_iterator_reset(renderer->iterator, NULL);
+ mafw_gst_renderer_set_media_playlist(renderer);
+ break;
+ default:
+ g_critical("Movement not controlled");
+ }
+}
+
+static void _do_previous(MafwGstRendererState *self, GError **error)
+{
+ MafwGstRenderer *renderer = NULL;
+ MafwGstRendererMovementResult value = MAFW_GST_RENDERER_MOVE_RESULT_OK;
+
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ value = mafw_gst_renderer_move(renderer,
+ MAFW_GST_RENDERER_MOVE_TYPE_PREV,
+ 0, error);
+
+ switch (value) {
+ case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
+ case MAFW_GST_RENDERER_MOVE_RESULT_OK:
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_NO_MEDIA,
+ "There is no playlist or media to play");
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
+
+ mafw_playlist_iterator_move_to_last(renderer->iterator, NULL);
+ mafw_gst_renderer_set_media_playlist(renderer);
+ break;
+ default:
+ g_critical("Movement not controlled");
+ }
+}
+
+static void _do_goto_index(MafwGstRendererState *self, guint index,
+ GError **error)
+{
+ MafwGstRenderer *renderer = NULL;
+ MafwGstRendererMovementResult value = MAFW_GST_RENDERER_MOVE_RESULT_OK;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ value = mafw_gst_renderer_move(renderer,
+ MAFW_GST_RENDERER_MOVE_TYPE_INDEX,
+ index, error);
+
+ switch (value) {
+ case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
+ case MAFW_GST_RENDERER_MOVE_RESULT_OK:
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_NO_MEDIA,
+ "There is no playlist or media to play");
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_INDEX_OUT_OF_BOUNDS,
+ "Index is out of bounds");
+ break;
+ default:
+ g_critical("Movement not controlled");
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Notification metatada
+ ----------------------------------------------------------------------------*/
+
+static void _notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error)
+{
+ g_debug("running _notify_metadata...");
+ /* This happens because we issued a play() command, this moved us to
+ Transitioning state, waiting for the URL of the objectid to play,
+ but before we got the URL and moved to Playing state, a stop()
+ command was issued. Now we got the results of the stopped play()
+ command, so we just ignore the result and stay in Stopped state. */
+
+}
+
+/*----------------------------------------------------------------------------
+ Playlist editing signals
+ ----------------------------------------------------------------------------*/
+
+static void _playlist_contents_changed(MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self));
+
+ /* Do nothing, we just stay in Stopped state in any case */
+}
+
+/*----------------------------------------------------------------------------
+ Property methods
+ ----------------------------------------------------------------------------*/
+
+GValue* _get_property_value(MafwGstRendererState *self, const gchar *name)
+{
+ GValue *value = NULL;
+
+ g_return_val_if_fail(MAFW_IS_GST_RENDERER_STATE_STOPPED(self), value);
+
+ if (!g_strcmp0(name, MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS)) {
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_STRING);
+ g_value_set_string(value, "");
+ }
+
+ return value;
+}
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef MAFW_GST_RENDERER_STATE_STOPPED_H
+#define MAFW_GST_RENDERER_STATE_STOPPED_H
+
+
+#include "mafw-gst-renderer.h"
+#include "mafw-gst-renderer-state.h"
+
+G_BEGIN_DECLS
+
+/*----------------------------------------------------------------------------
+ GObject type conversion macros
+ ----------------------------------------------------------------------------*/
+
+#define MAFW_TYPE_GST_RENDERER_STATE_STOPPED \
+ (mafw_gst_renderer_state_stopped_get_type())
+#define MAFW_GST_RENDERER_STATE_STOPPED(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_GST_RENDERER_STATE_STOPPED, \
+ MafwGstRendererStateStopped))
+#define MAFW_IS_GST_RENDERER_STATE_STOPPED(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_GST_RENDERER_STATE_STOPPED))
+#define MAFW_GST_RENDERER_STATE_STOPPED_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_GST_RENDERER_STATE_STOPPED, \
+ MafwGstRendererStateStopped))
+#define MAFW_GST_RENDERER_STATE_STOPPED_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_GST_RENDERER_STATE_STOPPED, \
+ MafwGstRendererStateStoppedClass))
+#define MAFW_IS_GST_RENDERER_STATE_STOPPED_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_GST_RENDERER_STATE_STOPPED))
+
+/*----------------------------------------------------------------------------
+ Type definitions
+ ----------------------------------------------------------------------------*/
+
+
+typedef struct _MafwGstRendererStateStopped MafwGstRendererStateStopped;
+typedef struct _MafwGstRendererStateStoppedClass MafwGstRendererStateStoppedClass;
+
+struct _MafwGstRendererStateStoppedClass {
+ MafwGstRendererStateClass parent_class;
+};
+
+struct _MafwGstRendererStateStopped {
+ MafwGstRendererState parent;
+};
+
+GType mafw_gst_renderer_state_stopped_get_type(void);
+
+GObject *mafw_gst_renderer_state_stopped_new(MafwGstRenderer *renderer);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <string.h>
+#include "mafw-gst-renderer-state-transitioning.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-state-transitioning"
+
+#define UPDATE_DELAY 10
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+static void _do_play(MafwGstRendererState *self, GError **error);
+static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
+ GError **error);
+static void _do_pause(MafwGstRendererState *self, GError **error);
+static void _do_stop(MafwGstRendererState *self, GError **error);
+static void _do_resume(MafwGstRendererState *self, GError **error);
+static void _do_get_position(MafwGstRendererState *self, gint *seconds,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+static void _do_next(MafwGstRendererState *self, GError **error);
+static void _do_previous(MafwGstRendererState *self,GError **error);
+static void _do_goto_index(MafwGstRendererState *self, guint index,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Notification metatada
+ ----------------------------------------------------------------------------*/
+
+static void _notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Notification worker
+ ----------------------------------------------------------------------------*/
+
+static void _notify_play(MafwGstRendererState *self, GError **error);
+static void _notify_pause(MafwGstRendererState *self,GError **error);
+
+static void _notify_buffer_status(MafwGstRendererState *self,
+ gdouble percent,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Playlist editing signals
+ ----------------------------------------------------------------------------*/
+
+static void _playlist_contents_changed(MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Property methods
+ ----------------------------------------------------------------------------*/
+
+static GValue* _get_property_value(MafwGstRendererState *self,
+ const gchar *name);
+
+/*----------------------------------------------------------------------------
+ GObject initialization
+ ----------------------------------------------------------------------------*/
+
+G_DEFINE_TYPE(MafwGstRendererStateTransitioning,
+ mafw_gst_renderer_state_transitioning,
+ MAFW_TYPE_GST_RENDERER_STATE);
+
+static void mafw_gst_renderer_state_transitioning_init(
+ MafwGstRendererStateTransitioning *self)
+{
+}
+
+static void mafw_gst_renderer_state_transitioning_class_init(
+ MafwGstRendererStateTransitioningClass *klass)
+{
+ MafwGstRendererStateClass *state_klass ;
+
+ state_klass = MAFW_GST_RENDERER_STATE_CLASS(klass);
+ g_return_if_fail(state_klass != NULL);
+
+ state_klass->name = g_strdup("Transitioning");
+
+ /* Playback */
+
+ state_klass->play = _do_play;
+ state_klass->play_object = _do_play_object;
+ state_klass->stop = _do_stop;
+ state_klass->pause = _do_pause;
+ state_klass->resume = _do_resume;
+ state_klass->get_position = _do_get_position;
+
+ /* Playlist */
+
+ state_klass->next = _do_next;
+ state_klass->previous = _do_previous;
+ state_klass->goto_index = _do_goto_index;
+
+ /* Metadata */
+
+ state_klass->notify_metadata = _notify_metadata;
+
+ /* Notification worker */
+
+ state_klass->notify_play = _notify_play;
+ state_klass->notify_pause = _notify_pause;
+ state_klass->notify_buffer_status = _notify_buffer_status;
+
+ /* Playlist editing signals */
+
+ state_klass->playlist_contents_changed =
+ _playlist_contents_changed;
+
+ /* Property methods */
+
+ state_klass->get_property_value = _get_property_value;
+}
+
+GObject *mafw_gst_renderer_state_transitioning_new(MafwGstRenderer *renderer)
+{
+ MafwGstRendererState *state;
+
+ state = MAFW_GST_RENDERER_STATE(
+ g_object_new(MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING, NULL));
+ state->renderer = renderer;
+
+ return G_OBJECT(state);
+}
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+static void _do_play(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+ mafw_gst_renderer_state_do_play(self, error);
+}
+
+static void _do_play_object(MafwGstRendererState *self, const gchar *object_id,
+ GError **error)
+{
+ MafwGstRendererPlaybackMode cur_mode, prev_mode;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+
+ prev_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+ mafw_gst_renderer_state_do_play_object(self, object_id, error);
+ cur_mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+
+ /* If this happens it means that we interrupted playlist playback
+ so let's resume it when play_object is finished */
+ if (cur_mode != prev_mode) {
+ self->renderer->resume_playlist = TRUE;
+ }
+}
+
+static void _do_stop(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+
+ /* Stop playback */
+ mafw_gst_renderer_state_do_stop(self, error);
+}
+
+static void _do_pause(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+ g_debug("Got pause while transitioning");
+ self->renderer->worker->stay_paused = TRUE;
+}
+
+static void _do_resume(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+ if (self->renderer->worker->stay_paused) {
+ g_debug("Got resume while transitioning/paused");
+ self->renderer->worker->stay_paused = FALSE;
+ } else {
+ g_set_error(error, MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_CANNOT_PLAY,
+ "cannot resume in transitioning state without "
+ "having paused before");
+ }
+}
+
+static void _do_get_position(MafwGstRendererState *self, gint *seconds,
+ GError **error)
+{
+ *seconds = 0;
+}
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+static void _do_next(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+ mafw_gst_renderer_state_do_next(self, error);
+}
+
+static void _do_previous(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+ mafw_gst_renderer_state_do_prev(self, error);
+}
+
+static void _do_goto_index(MafwGstRendererState *self, guint index,
+ GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+ mafw_gst_renderer_state_do_goto_index(self, index, error);
+}
+
+/*----------------------------------------------------------------------------
+ Notification metatada
+ ----------------------------------------------------------------------------*/
+
+static void _notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+
+ MafwGstRenderer *renderer;
+ GValue *mval;
+ gpointer value;
+ gint nuris, i;
+ gchar **uris;
+ gchar *uri;
+
+ g_debug("running _notify_metadata...");
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ /* If we have received metadata for the item that we are playing
+ then play it */
+ if (object_id && renderer->media->object_id &&
+ !strcmp(object_id, renderer->media->object_id)) {
+ /* Check how many uris provide the object_id */
+ value = g_hash_table_lookup(metadata, MAFW_METADATA_KEY_URI);
+ nuris = mafw_metadata_nvalues(value);
+ if (nuris == 1) {
+ mval = mafw_metadata_first(metadata,
+ MAFW_METADATA_KEY_URI);
+ g_assert(mval);
+ g_free(renderer->media->uri);
+ renderer->media->uri =
+ g_strdup(g_value_get_string(mval));
+ uri = renderer->media->uri;
+ } else if (nuris > 1) {
+ uris = g_new0(gchar *, nuris + 1);
+ for (i = 0; i < nuris; i++) {
+ mval = g_value_array_get_nth(value, i);
+ uris[i] = (gchar *) g_value_get_string(mval);
+ }
+
+ /* Try the first URI, if that fails to play back another
+ * one will be selected until we get a successful one or
+ * all failed. On success, the selected URI will be
+ * emitted as metadata */
+ g_free(renderer->media->uri);
+ renderer->media->uri = g_strdup(uris[0]);
+ } else {
+ g_assert_not_reached();
+ }
+
+ /* Set seekability property; currently, if several uris are
+ * provided it uses the value of the first uri. If later another
+ * uri is actually played, then this value should be changed. */
+ mval = mafw_metadata_first(metadata,
+ MAFW_METADATA_KEY_IS_SEEKABLE);
+ if (mval != NULL) {
+ renderer->media->seekability =
+ g_value_get_boolean(mval) ?
+ SEEKABILITY_SEEKABLE : SEEKABILITY_NO_SEEKABLE;
+ g_debug("_notify_metadata: source seekability %d",
+ renderer->media->seekability);
+ } else {
+ renderer->media->seekability = SEEKABILITY_UNKNOWN;
+ g_debug("_notify_metadata: source seekability unknown");
+ }
+
+ /* Check for source duration to keep it updated if needed */
+ mval = mafw_metadata_first(metadata,
+ MAFW_METADATA_KEY_DURATION);
+
+ if (mval != NULL) {
+ renderer->media->duration = g_value_get_int(mval);
+ g_debug("_notify_metadata: source duration %d",
+ renderer->media->duration);
+ } else {
+ renderer->media->duration = -1;
+ g_debug("_notify_metadata: source duration unknown");
+ }
+
+ /* Play the available uri(s) */
+ if (nuris == 1) {
+ mafw_gst_renderer_worker_play(renderer->worker, uri, NULL);
+ } else {
+ mafw_gst_renderer_worker_play_alternatives(
+ renderer->worker, uris);
+ g_free(uris);
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Notification worker
+ ----------------------------------------------------------------------------*/
+
+static void _notify_play(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+
+ MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ if (renderer->media->object_id)
+ {
+ renderer->update_playcount_id = g_timeout_add_seconds(
+ UPDATE_DELAY,
+ mafw_gst_renderer_update_stats,
+ renderer);
+ }
+
+ mafw_gst_renderer_set_state(renderer, Playing);
+}
+
+static void _notify_pause(MafwGstRendererState *self, GError **error)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+
+ MafwGstRenderer *renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+ self->renderer->worker->stay_paused = FALSE;
+ mafw_gst_renderer_set_state(renderer, Paused);
+}
+
+static void _notify_buffer_status(MafwGstRendererState *self, gdouble percent,
+ GError **error)
+{
+ mafw_gst_renderer_state_do_notify_buffer_status (self, percent, error);
+}
+
+/*----------------------------------------------------------------------------
+ Playlist editing signals
+ ----------------------------------------------------------------------------*/
+
+static void _playlist_contents_changed(MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error)
+{
+ MafwGstRendererPlaybackMode mode;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self));
+
+ /* Play the new index only if we are not in standalone mode.
+ Otherwise, when play_object finishes the new item will be
+ played if that's been suggested with renderer->resume_playlist */
+ mode = mafw_gst_renderer_get_playback_mode(self->renderer);
+ if (clip_changed && mode == MAFW_GST_RENDERER_MODE_PLAYLIST) {
+ mafw_gst_renderer_state_do_play(self, error);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Property methods
+ ----------------------------------------------------------------------------*/
+
+GValue* _get_property_value(MafwGstRendererState *self, const gchar *name)
+{
+ GValue *value = NULL;
+
+ g_return_val_if_fail(MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(self),
+ value);
+
+ if (!g_strcmp0(name, MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS)) {
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_STRING);
+ g_value_set_string(value, "");
+ }
+
+ return value;
+}
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef MAFW_GST_RENDERER_STATE_TRANSITIONING_H
+#define MAFW_GST_RENDERER_STATE_TRANSITIONING_H
+
+
+#include "mafw-gst-renderer.h"
+#include "mafw-gst-renderer-state.h"
+#include "mafw-gst-renderer-utils.h"
+
+G_BEGIN_DECLS
+
+/*----------------------------------------------------------------------------
+ GObject type conversion macros
+ ----------------------------------------------------------------------------*/
+
+#define MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING \
+ (mafw_gst_renderer_state_transitioning_get_type())
+#define MAFW_GST_RENDERER_STATE_(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING, \
+ MafwGstRendererStateTransitioning))
+#define MAFW_IS_GST_RENDERER_STATE_TRANSITIONING(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+ MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING))
+#define MAFW_GST_RENDERER_STATE_TRANSITIONING_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), \
+ MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING, \
+ MafwGstRendererStateTransitioning))
+#define MAFW_GST_RENDERER_STATE_TRANSITIONING_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), \
+ MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING, \
+ MafwGstRendererStateTransitioningClass))
+#define MAFW_IS_GST_RENDERER_STATE_TRANSITIONING_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), \
+ MAFW_TYPE_GST_RENDERER_STATE_TRANSITIONING))
+
+/*----------------------------------------------------------------------------
+ Type definitions
+ ----------------------------------------------------------------------------*/
+
+
+typedef struct _MafwGstRendererStateTransitioning MafwGstRendererStateTransitioning;
+typedef struct _MafwGstRendererStateTransitioningClass MafwGstRendererStateTransitioningClass;
+
+struct _MafwGstRendererStateTransitioningClass {
+ MafwGstRendererStateClass parent_class;
+};
+
+struct _MafwGstRendererStateTransitioning {
+ MafwGstRendererState parent;
+};
+
+GType mafw_gst_renderer_state_transitioning_get_type(void);
+
+GObject *mafw_gst_renderer_state_transitioning_new(MafwGstRenderer *renderer);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libmafw/mafw-renderer.h>
+#include <libmafw/mafw-errors.h>
+
+#include "mafw-gst-renderer.h"
+#include "mafw-gst-renderer-state.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-state"
+
+/*----------------------------------------------------------------------------
+ Default playback implementations
+ ----------------------------------------------------------------------------*/
+
+static void _default_play(MafwGstRendererState *self, GError **error)
+{
+ g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
+ "Play: operation not allowed in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+
+static void _default_play_object(MafwGstRendererState *self,
+ const gchar *objectid,
+ GError **error)
+{
+ g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
+ "Play object: operation not allowed in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+static void _default_stop(MafwGstRendererState *self, GError **error)
+{
+ g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_STOP,
+ "Stop: operation not allowed in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+static void _default_pause(MafwGstRendererState *self, GError **error)
+{
+ g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PAUSE,
+ "Pause: operation not allowed in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+static void _default_resume(MafwGstRendererState *self, GError **error)
+{
+ g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
+ "Resume: operation not allowed in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+static void _default_set_position (MafwGstRendererState *self,
+ MafwRendererSeekMode mode, gint seconds,
+ GError **error)
+{
+ g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
+ "Set position: operation not allowed in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+static void _default_get_position (MafwGstRendererState *self,
+ gint *seconds,
+ GError **error)
+{
+ g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_GET_POSITION,
+ "Get position: operation not allowed in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+/*----------------------------------------------------------------------------
+ Default playlist implementations
+ ----------------------------------------------------------------------------*/
+
+static void _default_next(MafwGstRendererState *self, GError **error)
+{
+ g_set_error(error, MAFW_EXTENSION_ERROR, MAFW_EXTENSION_ERROR_FAILED,
+ "Next: operation not allowed in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+static void _default_previous(MafwGstRendererState *self, GError **error)
+{
+ g_set_error(error, MAFW_EXTENSION_ERROR, MAFW_EXTENSION_ERROR_FAILED,
+ "Previous: Operation not allowed in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+static void _default_goto_index(MafwGstRendererState *self, guint index,
+ GError **error)
+{
+ g_set_error(error, MAFW_EXTENSION_ERROR, MAFW_EXTENSION_ERROR_FAILED,
+ "Goto index: operation not allowed in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+/*----------------------------------------------------------------------------
+ Default notify metadata implementation
+ ----------------------------------------------------------------------------*/
+
+static void _default_notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error)
+{
+
+ g_critical("Notify metadata: got unexpected metadata in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+/*----------------------------------------------------------------------------
+ Default notify worker implementations
+ ----------------------------------------------------------------------------*/
+
+static void _default_notify_play(MafwGstRendererState *self, GError **error)
+{
+ g_critical("Notify play: unexpected Play notification received in %s "
+ "state", MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+static void _default_notify_pause(MafwGstRendererState *self, GError **error)
+{
+
+ g_critical("Notify pause: unexpected Pause notification received %s "
+ "state", MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+static void _default_notify_seek(MafwGstRendererState *self, GError **error)
+{
+ g_critical("Notify seek: incorrect operation in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+static void _default_notify_buffer_status(MafwGstRendererState *self,
+ gdouble percent,
+ GError **error)
+{
+ g_critical("Notify buffer status: incorrect operation in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+
+static void _default_notify_eos(MafwGstRendererState *self, GError **error)
+{
+ g_critical("Notify eos: incorrect operation in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+/*----------------------------------------------------------------------------
+ Default playlist editing signal handlers implementation
+ ----------------------------------------------------------------------------*/
+
+static void _default_playlist_contents_changed(MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error)
+{
+ g_warning("playlist::contents-changed not implemented in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+/*----------------------------------------------------------------------------
+ Default property methods implementation
+ ----------------------------------------------------------------------------*/
+
+static GValue* _default_get_property_value(MafwGstRendererState *self,
+ const gchar *name)
+{
+ g_warning("get_property_value function not implemented in %s state",
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+ return NULL;
+}
+
+/*----------------------------------------------------------------------------
+ Default memory card event handlers implementation
+ ----------------------------------------------------------------------------*/
+
+static void _default_handle_pre_unmount(MafwGstRendererState *self,
+ const gchar *mount_point)
+{
+ g_debug("pre-unmount signal received: %s in state %s", mount_point,
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
+}
+
+/*----------------------------------------------------------------------------
+ GObject initialization
+ ----------------------------------------------------------------------------*/
+
+G_DEFINE_ABSTRACT_TYPE(MafwGstRendererState, mafw_gst_renderer_state,
+ G_TYPE_OBJECT);
+
+static void mafw_gst_renderer_state_init(MafwGstRendererState *self)
+{
+}
+
+static void mafw_gst_renderer_state_class_init(MafwGstRendererStateClass *klass)
+{
+ /* Playback */
+
+ klass->play = _default_play;
+ klass->play_object = _default_play_object;
+ klass->stop = _default_stop;
+ klass->pause = _default_pause;
+ klass->resume = _default_resume;
+ klass->set_position = _default_set_position;
+ klass->get_position = _default_get_position;
+
+ /* Playlist */
+
+ klass->next = _default_next;
+ klass->previous = _default_previous;
+ klass->goto_index = _default_goto_index;
+
+ /* Notification metadata */
+
+ klass->notify_metadata = _default_notify_metadata;
+
+ /* Notification worker */
+
+ klass->notify_play = _default_notify_play;
+ klass->notify_pause = _default_notify_pause;
+ klass->notify_seek = _default_notify_seek;
+ klass->notify_buffer_status = _default_notify_buffer_status;
+ klass->notify_eos = _default_notify_eos;
+
+ klass->notify_eos = _default_notify_eos;
+
+ /* Playlist editing signals */
+
+ klass->playlist_contents_changed =
+ _default_playlist_contents_changed;
+
+ /* Property methods */
+
+ klass->get_property_value = _default_get_property_value;
+
+ /* Memory card event handlers */
+
+ klass->handle_pre_unmount = _default_handle_pre_unmount;
+}
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_play(MafwGstRendererState *self, GError **error)
+
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->play(self, error);
+}
+
+void mafw_gst_renderer_state_play_object(MafwGstRendererState *self,
+ const gchar *object_id,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->play_object(self, object_id,
+ error);
+}
+
+void mafw_gst_renderer_state_stop(MafwGstRendererState *self, GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->stop(self, error);
+}
+
+void mafw_gst_renderer_state_pause(MafwGstRendererState *self, GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->pause(self, error);
+}
+
+void mafw_gst_renderer_state_resume(MafwGstRendererState *self, GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->resume(self, error);
+}
+
+void mafw_gst_renderer_state_set_position(MafwGstRendererState *self,
+ MafwRendererSeekMode mode, gint seconds,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->set_position(self, mode, seconds,
+ error);
+}
+
+void mafw_gst_renderer_state_get_position(MafwGstRendererState *self,
+ gint *seconds,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->get_position(self, seconds,
+ error);
+}
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_next(MafwGstRendererState *self, GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->next(self, error);
+}
+
+void mafw_gst_renderer_state_previous(MafwGstRendererState *self, GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->previous(self, error);
+}
+
+void mafw_gst_renderer_state_goto_index(MafwGstRendererState *self, guint index,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->goto_index(self, index, error);
+
+}
+
+/*----------------------------------------------------------------------------
+ Notification metatada
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_metadata(self, object_id,
+ metadata,
+ error);
+}
+
+/*----------------------------------------------------------------------------
+ Notification worker
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_notify_play(MafwGstRendererState *self,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_play(self, error);
+}
+
+void mafw_gst_renderer_state_notify_pause(MafwGstRendererState *self,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_pause(self, error);
+}
+
+void mafw_gst_renderer_state_notify_seek(MafwGstRendererState *self,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_seek(self, error);
+}
+
+void mafw_gst_renderer_state_notify_buffer_status(MafwGstRendererState *self,
+ gdouble percent,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_buffer_status(self,
+ percent,
+ error);
+}
+
+void mafw_gst_renderer_state_notify_eos(MafwGstRendererState *self,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_eos(self, error);
+}
+
+/*----------------------------------------------------------------------------
+ Playlist editing handlers
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_playlist_contents_changed_handler(
+ MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->playlist_contents_changed(
+ self,
+ clip_changed,
+ error);
+}
+
+/*----------------------------------------------------------------------------
+ Property methods
+ ----------------------------------------------------------------------------*/
+
+GValue* mafw_gst_renderer_state_get_property_value(MafwGstRendererState *self,
+ const gchar *name)
+{
+ return MAFW_GST_RENDERER_STATE_GET_CLASS(self)->get_property_value(
+ self,
+ name);
+}
+
+/*----------------------------------------------------------------------------
+ Memory card event handlers
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_handle_pre_unmount(MafwGstRendererState *self,
+ const gchar *mount_point)
+{
+ MAFW_GST_RENDERER_STATE_GET_CLASS(self)->
+ handle_pre_unmount(self, mount_point);
+}
+
+/*----------------------------------------------------------------------------
+ Helpers
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_do_play(MafwGstRendererState *self, GError **error)
+{
+ MafwGstRenderer *renderer;
+ GError *gm_error = NULL;
+ MafwGstRendererPlaybackMode mode;
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ /* Stop any on going playback */
+ mafw_gst_renderer_worker_stop(renderer->worker);
+
+ /* Play command only affects playlists, so switch to playlist
+ mode first if necessary */
+ mode = mafw_gst_renderer_get_playback_mode(renderer);
+ if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
+ mafw_gst_renderer_set_playback_mode(
+ renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
+ mafw_gst_renderer_set_media_playlist(renderer);
+ }
+
+ /* Do we have any objectid to play? Otherwise we cannot do it */
+ if (renderer->media->object_id) {
+ /* If so, resolve URI for this objectid */
+ mafw_gst_renderer_get_metadata(renderer,
+ renderer->media->object_id,
+ &gm_error);
+ if (gm_error) {
+ MafwGstRendererErrorClosure *error_closure;
+ if (error) {
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_NO_MEDIA,
+ "Unable to find media");
+ }
+
+ /* This is a playback error: execute error policy */
+ error_closure = g_new0(MafwGstRendererErrorClosure, 1);
+ error_closure->renderer = renderer;
+ error_closure->error = g_error_copy(gm_error);
+ g_idle_add(mafw_gst_renderer_manage_error_idle,
+ error_closure);
+
+ g_error_free(gm_error);
+ } else {
+ mafw_gst_renderer_set_state(renderer, Transitioning);
+ }
+ } else if (error) {
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_NO_MEDIA,
+ "There is no media to play");
+ mafw_gst_renderer_set_state(renderer, Stopped);
+ }
+}
+
+void mafw_gst_renderer_state_do_play_object(MafwGstRendererState *self,
+ const gchar *object_id,
+ GError **error)
+{
+ MafwGstRenderer *renderer;
+ GError *gm_error = NULL;
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ /* Stop any ongoing playback */
+ mafw_gst_renderer_worker_stop(renderer->worker);
+
+ if (object_id) {
+ /* Switch to standalone mode */
+ mafw_gst_renderer_set_playback_mode(
+ renderer, MAFW_GST_RENDERER_MODE_STANDALONE);
+
+ mafw_gst_renderer_set_object(renderer, object_id);
+ mafw_gst_renderer_get_metadata(renderer,
+ renderer->media->object_id,
+ &gm_error);
+ if (gm_error) {
+ MafwGstRendererErrorClosure *error_closure;
+ if (error) {
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_NO_MEDIA,
+ "Unable to find media");
+ }
+
+ /* This is a playback error: execute error policy */
+ error_closure = g_new0(MafwGstRendererErrorClosure, 1);
+ error_closure->renderer = renderer;
+ error_closure->error = g_error_copy(gm_error);
+ g_idle_add(mafw_gst_renderer_manage_error_idle,
+ error_closure);
+ g_error_free(gm_error);
+ } else {
+ /* Play object has been successful */
+ mafw_gst_renderer_set_state(renderer, Transitioning);
+ }
+ } else if (error) {
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_NO_MEDIA,
+ "There is no media to play");
+ mafw_gst_renderer_set_state(renderer, Stopped);
+ }
+}
+
+void mafw_gst_renderer_state_do_stop(MafwGstRendererState *self, GError **error)
+{
+ MafwGstRenderer *renderer;
+ MafwGstRendererPlaybackMode mode;
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ /* Stop any ongoing playback */
+ mafw_gst_renderer_worker_stop(renderer->worker);
+
+ /* Cancel update */
+ if (renderer->update_playcount_id > 0) {
+ g_source_remove(renderer->update_playcount_id);
+ renderer->update_playcount_id = 0;
+ }
+
+ /* Set new state */
+ mafw_gst_renderer_set_state(renderer, Stopped);
+
+ /* If we were playing a standalone object, then go back
+ to playlist mode and stay stopped */
+ mode = mafw_gst_renderer_get_playback_mode(renderer);
+ if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
+ mafw_gst_renderer_set_playback_mode(
+ renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
+ mafw_gst_renderer_set_media_playlist(renderer);
+ }
+}
+
+void mafw_gst_renderer_state_do_next (MafwGstRendererState *self, GError **error)
+{
+ MafwGstRenderer *renderer;
+ MafwGstRendererMovementResult move_type;
+ MafwGstRendererPlaybackMode mode;
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ /* If we are in standalone mode, we switch back to playlist
+ * mode. Then we resume playback only if renderer->resume_playlist
+ * was set.
+ * If we are in playlist mode we just move to the next and
+ * play.
+ */
+ mode = mafw_gst_renderer_get_playback_mode(renderer);
+ if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
+ mafw_gst_renderer_set_playback_mode(
+ renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
+ mafw_gst_renderer_set_media_playlist(renderer);
+ }
+
+ move_type = mafw_gst_renderer_move(renderer,
+ MAFW_GST_RENDERER_MOVE_TYPE_NEXT,
+ 0, error);
+ switch (move_type) {
+ case MAFW_GST_RENDERER_MOVE_RESULT_OK:
+ if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST ||
+ renderer->resume_playlist) {
+ /* We issued the comand in playlist mode, or
+ in standalone mode but with resume_playlist
+ set, so let's play the new item */
+ mafw_gst_renderer_state_play(self, error);
+
+ } else {
+ /* We issued the command in standalone mode and we
+ do not want to resume playlist, so let's
+ move to Stopped */
+ mafw_gst_renderer_state_stop(self, NULL);
+ }
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_NO_MEDIA,
+ "There is no playlist or media to play");
+ mafw_gst_renderer_state_stop(self, NULL);
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
+ /* Normal mode */
+ mafw_playlist_iterator_reset(renderer->iterator, NULL);
+ mafw_gst_renderer_set_media_playlist(renderer);
+ mafw_gst_renderer_state_play(self, error);
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
+ break;
+ default:
+ g_critical("Movement not controlled");
+ }
+}
+
+void mafw_gst_renderer_state_do_prev(MafwGstRendererState *self, GError **error)
+{
+ MafwGstRenderer *renderer;
+ MafwGstRendererMovementResult move_type;
+ MafwGstRendererPlaybackMode mode;
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ mode = mafw_gst_renderer_get_playback_mode(renderer);
+ if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
+ mafw_gst_renderer_set_playback_mode(
+ renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
+ mafw_gst_renderer_set_media_playlist(renderer);
+ }
+
+ move_type = mafw_gst_renderer_move(renderer,
+ MAFW_GST_RENDERER_MOVE_TYPE_PREV,
+ 0, error);
+ switch (move_type) {
+ case MAFW_GST_RENDERER_MOVE_RESULT_OK:
+ if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST ||
+ renderer->resume_playlist) {
+ /* We issued the comand in playlist mode, or
+ in standalone mode but with resume_playlist
+ set, so let's play the new item */
+ mafw_gst_renderer_state_play(self, error);
+
+ } else {
+ /* We issued the command in standalone mode and we
+ do not want to resume playlist, so let's
+ move to Stopped */
+ mafw_gst_renderer_state_stop(self, NULL);
+ }
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_NO_MEDIA,
+ "There is no playlist or media to play");
+ mafw_gst_renderer_state_stop(self, NULL);
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
+ /* Normal mode */
+ mafw_playlist_iterator_move_to_last(renderer->iterator, NULL);
+ mafw_gst_renderer_set_media_playlist(renderer);
+ mafw_gst_renderer_state_play(self, error);
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
+ break;
+ default:
+ g_critical("Movement not controlled");
+ }
+}
+
+
+void mafw_gst_renderer_state_do_goto_index(MafwGstRendererState *self,
+ guint index,
+ GError **error)
+{
+ MafwGstRenderer *renderer;
+ MafwGstRendererMovementResult move_type;
+ MafwGstRendererPlaybackMode mode;
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ /* If we are in standalone mode, we switch back to playlist
+ * mode. Then we resume playback only if renderer->resume_playlist
+ * was set.
+ * If we are in playlist mode we just move to the next and
+ * play.
+ */
+ mode = mafw_gst_renderer_get_playback_mode(renderer);
+ if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
+ mafw_gst_renderer_set_playback_mode(
+ renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
+ mafw_gst_renderer_set_media_playlist(renderer);
+ }
+
+ move_type = mafw_gst_renderer_move(renderer, MAFW_GST_RENDERER_MOVE_TYPE_INDEX, index, error);
+
+ switch (move_type) {
+ case MAFW_GST_RENDERER_MOVE_RESULT_OK:
+ if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST ||
+ renderer->resume_playlist) {
+ /* We issued the comand in playlist mode, or
+ in standalone mode but with resume_playlist
+ set, so let's play the new item */
+ mafw_gst_renderer_state_play(self, error);
+
+ } else {
+ /* We issued the command in standalone mode and we
+ do not want to resume playlist, so let's
+ move to Stopped */
+ mafw_gst_renderer_state_stop(self, NULL);
+ }
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_NO_MEDIA,
+ "There is no playlist or media to play");
+ mafw_gst_renderer_state_stop(self, NULL);
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
+ g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_INDEX_OUT_OF_BOUNDS,
+ "Index is out of bounds");
+ mafw_gst_renderer_state_stop(self, NULL);
+ break;
+ case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
+ break;
+ default:
+ g_critical("Movement not controlled");
+ }
+}
+
+void mafw_gst_renderer_state_do_get_position(MafwGstRendererState *self,
+ gint *seconds,
+ GError **error)
+{
+ *seconds = mafw_gst_renderer_worker_get_position(self->renderer->worker);
+ if (*seconds < 0) {
+ *seconds = 0;
+ g_set_error(error, MAFW_EXTENSION_ERROR,
+ MAFW_RENDERER_ERROR_CANNOT_GET_POSITION,
+ "Position query failed");
+ }
+}
+
+void mafw_gst_renderer_state_do_set_position(MafwGstRendererState *self,
+ MafwRendererSeekMode mode,
+ gint seconds,
+ GError **error)
+{
+ MafwGstRenderer *renderer;
+ GstSeekType seektype;
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ /* TODO Gst stuff should be moved to worker, not handled here... */
+ if (mode == SeekAbsolute) {
+ if (seconds < 0) {
+ seektype = GST_SEEK_TYPE_END;
+ seconds *= -1;
+ } else {
+ seektype = GST_SEEK_TYPE_SET;
+ }
+ } else if (mode == SeekRelative) {
+ seektype = GST_SEEK_TYPE_CUR;
+ } else {
+ g_critical("Unknown seek mode: %d", mode);
+ g_set_error(error, MAFW_EXTENSION_ERROR,
+ MAFW_EXTENSION_ERROR_INVALID_PARAMS,
+ "Unknown seek mode: %d", mode);
+ return;
+ }
+ if (renderer->seek_pending) {
+ g_debug("seek pending, storing position %d", seconds);
+ renderer->seek_type_pending = seektype;
+ renderer->seeking_to = seconds;
+ } else {
+ renderer->seek_pending = TRUE;
+ mafw_gst_renderer_worker_set_position(renderer->worker,
+ seektype,
+ seconds,
+ error);
+ }
+}
+
+void mafw_gst_renderer_state_do_notify_seek(MafwGstRendererState *self,
+ GError **error)
+{
+ MafwGstRenderer *renderer;
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ if (renderer->seeking_to != -1) {
+ renderer->seek_pending = TRUE;
+ mafw_gst_renderer_worker_set_position(renderer->worker,
+ renderer->seek_type_pending,
+ renderer->seeking_to,
+ NULL);
+ } else {
+ renderer->seek_pending = FALSE;
+ }
+ renderer->seeking_to = -1;
+}
+
+void mafw_gst_renderer_state_do_notify_buffer_status(MafwGstRendererState *self,
+ gdouble percent,
+ GError **error)
+{
+ MafwGstRenderer *renderer = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER_STATE(self));
+
+ renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
+
+ mafw_renderer_emit_buffering_info(MAFW_RENDERER(renderer), percent / 100.0);
+}
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef MAFW_GST_RENDERER_STATE_H
+#define MAFW_GST_RENDERER_STATE_H
+
+
+#include <glib-object.h>
+#include "mafw-gst-renderer-worker.h"
+
+/* Solving the cyclic dependencies */
+typedef struct _MafwGstRendererState MafwGstRendererState;
+typedef struct _MafwGstRendererStateClass MafwGstRendererStateClass;
+#include "mafw-gst-renderer.h"
+
+G_BEGIN_DECLS
+
+/*----------------------------------------------------------------------------
+ GObject type conversion macros
+ ----------------------------------------------------------------------------*/
+
+#define MAFW_TYPE_GST_RENDERER_STATE \
+ (mafw_gst_renderer_state_get_type())
+#define MAFW_GST_RENDERER_STATE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_GST_RENDERER_STATE, \
+ MafwGstRendererState))
+#define MAFW_IS_GST_RENDERER_STATE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_GST_RENDERER_STATE))
+#define MAFW_GST_RENDERER_STATE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_GST_RENDERER_STATE, \
+ MafwGstRendererStateClass))
+#define MAFW_GST_RENDERER_STATE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_GST_RENDERER_STATE, \
+ MafwGstRendererStateClass))
+#define MAFW_IS_GST_RENDERER_STATE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_GST_RENDERER_STATE))
+
+/*----------------------------------------------------------------------------
+ Type definitions
+ ----------------------------------------------------------------------------*/
+
+
+struct _MafwGstRendererStateClass {
+ GObjectClass parent_class;
+ const gchar* name;
+
+ /* Playback */
+
+ void (*play)(MafwGstRendererState *self, GError **error);
+ void (*play_object)(MafwGstRendererState *self, const gchar *object_id,
+ GError **error);
+ void (*stop)(MafwGstRendererState *self, GError **error);
+ void (*pause)(MafwGstRendererState *self, GError **error);
+ void (*resume)(MafwGstRendererState *self, GError **error);
+ void (*set_position) (MafwGstRendererState *self,
+ MafwRendererSeekMode mode, gint seconds,
+ GError **error);
+ void (*get_position) (MafwGstRendererState *self,
+ gint *seconds,
+ GError **error);
+
+ /* Playlist */
+
+ void (*next)(MafwGstRendererState *self, GError **error);
+ void (*previous)(MafwGstRendererState *self, GError **error);
+ void (*goto_index)(MafwGstRendererState *self, guint index,
+ GError **error);
+
+ /* Notification metadata */
+
+ void (*notify_metadata)(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error);
+
+
+ /* Notifications */
+
+ void (*notify_play)(MafwGstRendererState *self, GError **error);
+ void (*notify_pause)(MafwGstRendererState *self, GError **error);
+ void (*notify_seek)(MafwGstRendererState *self, GError **error);
+ void (*notify_buffer_status)(MafwGstRendererState *self, gdouble percent,
+ GError **error);
+ void (*notify_eos) (MafwGstRendererState *self, GError **error);
+
+ /* Playlist editing signals */
+
+ void (*playlist_contents_changed)(MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error);
+ /* Property methods */
+
+ GValue* (*get_property_value)(MafwGstRendererState *self,
+ const gchar *name);
+
+ /* Memory card event handlers */
+
+ void (*handle_pre_unmount)(MafwGstRendererState *self,
+ const gchar *mount_point);
+};
+
+struct _MafwGstRendererState {
+ GObject parent;
+
+ MafwGstRenderer *renderer;
+};
+
+GType mafw_gst_renderer_state_get_type(void);
+
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_play(MafwGstRendererState *self, GError **error);
+void mafw_gst_renderer_state_play_object(MafwGstRendererState *self,
+ const gchar *object_id,
+ GError **error);
+void mafw_gst_renderer_state_stop(MafwGstRendererState *self, GError **error);
+void mafw_gst_renderer_state_pause(MafwGstRendererState *self, GError **error);
+void mafw_gst_renderer_state_resume(MafwGstRendererState *self, GError **error);
+void mafw_gst_renderer_state_set_position(MafwGstRendererState *self,
+ MafwRendererSeekMode mode, gint seconds,
+ GError **error);
+void mafw_gst_renderer_state_get_position(MafwGstRendererState *self,
+ gint *seconds,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_next(MafwGstRendererState *self, GError **error);
+void mafw_gst_renderer_state_previous(MafwGstRendererState *self, GError **error);
+void mafw_gst_renderer_state_goto_index(MafwGstRendererState *self, guint index,
+ GError **error);
+
+
+/*----------------------------------------------------------------------------
+ Notification metatada
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_notify_metadata(MafwGstRendererState *self,
+ const gchar *object_id,
+ GHashTable *metadata,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Notification worker
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_notify_play(MafwGstRendererState *self,
+ GError **error);
+void mafw_gst_renderer_state_notify_pause(MafwGstRendererState *self,
+ GError **error);
+void mafw_gst_renderer_state_notify_seek(MafwGstRendererState *self,
+ GError **error);
+void mafw_gst_renderer_state_notify_buffer_status(MafwGstRendererState *self,
+ gdouble percent,
+ GError **error);
+void mafw_gst_renderer_state_notify_eos(MafwGstRendererState *self,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Playlist editing handlers
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_playlist_contents_changed_handler(
+ MafwGstRendererState *self,
+ gboolean clip_changed,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Property methods
+ ----------------------------------------------------------------------------*/
+
+GValue* mafw_gst_renderer_state_get_property_value(MafwGstRendererState *self,
+ const gchar *name);
+
+/*----------------------------------------------------------------------------
+ Memory card event handlers
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_handle_pre_unmount(MafwGstRendererState *self,
+ const gchar *mount_point);
+
+/*----------------------------------------------------------------------------
+ Helpers
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_state_do_play(MafwGstRendererState *self, GError **error);
+void mafw_gst_renderer_state_do_play_object(MafwGstRendererState *self,
+ const gchar *object_id,
+ GError **error);
+void mafw_gst_renderer_state_do_stop(MafwGstRendererState *self,
+ GError **error);
+void mafw_gst_renderer_state_do_next(MafwGstRendererState *self,
+ GError **error);
+void mafw_gst_renderer_state_do_prev(MafwGstRendererState *self,
+ GError **error);
+void mafw_gst_renderer_state_do_goto_index(MafwGstRendererState *self,
+ guint index,
+ GError **error);
+void mafw_gst_renderer_state_do_set_position(MafwGstRendererState *self,
+ MafwRendererSeekMode mode, gint seconds,
+ GError **error);
+void mafw_gst_renderer_state_do_get_position(MafwGstRendererState *self,
+ gint *seconds,
+ GError **error);
+void mafw_gst_renderer_state_do_notify_seek(MafwGstRendererState *self,
+ GError **error);
+void mafw_gst_renderer_state_do_notify_buffer_status(MafwGstRendererState *self,
+ gdouble percent,
+ GError **error);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+
+#include <string.h>
+#include <gio/gio.h>
+
+#include "mafw-gst-renderer-utils.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-utils"
+
+/**
+ * convert_utf8:
+ * @src: string.
+ * @dst: location for utf8 version of @src.
+ *
+ * Tries to convert @src into UTF-8, placing it into @dst.
+ *
+ * Returns: TRUE on success.
+ */
+gboolean convert_utf8(const gchar *src, gchar **dst)
+{
+ GError *error;
+
+ if (!src)
+ return FALSE;
+ if (g_utf8_validate(src, -1, NULL)) {
+ *dst = g_strdup(src);
+ return TRUE;
+ }
+ error = NULL;
+ *dst = g_locale_to_utf8(src, -1, NULL, NULL, &error);
+ if (error) {
+ g_warning("utf8 conversion failed '%s' (%d: %s)",
+ src, error->code, error->message);
+ g_error_free(error);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+gboolean uri_is_playlist(const gchar *uri) {
+ /* TODO: Return if the uri is a playlist or not, using the mime type
+ instead of the file extension. */
+ if ((g_str_has_suffix(uri, ".pls")) ||
+ (g_str_has_suffix(uri, ".m3u")) ||
+ (g_str_has_suffix(uri, ".smil")) ||
+ (g_str_has_suffix(uri, ".smi")) ||
+ (g_str_has_suffix(uri, ".wpl")) ||
+ (g_str_has_suffix(uri, ".wax")) ||
+ (g_str_has_suffix(uri, ".uni")) ||
+ (g_str_has_suffix(uri, ".ram")) ||
+/* (g_str_has_suffix(uri, ".ra")) || */
+ (g_str_has_suffix(uri, ".asx")) ||
+ (g_str_has_suffix(uri, ".rpm")))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * uri_is_stream:
+ * @uri: the URI to be checked.
+ *
+ * Check if given URI is a stream (not a local resource). To not depend on
+ * gnomevfs for this, we assume everything that doesn't start with "file://" is
+ * a stream.
+ *
+ * Returns: TRUE if the URI is not local.
+ */
+gboolean uri_is_stream(const gchar *uri)
+{
+ if (uri == NULL) {
+ return FALSE;
+ } else {
+ return !g_str_has_prefix(uri, "file://");
+ }
+}
+
+/*
+ * Imported from totem-uri.c
+ * Copyright (C) 2004 Bastien Nocera
+ */
+
+/* List from xine-lib's demux_sputext.c */
+static const char subtitle_ext[][4] = {
+ "sub",
+ "srt",
+ "smi",
+ "ssa",
+ "ass",
+ "asc"
+};
+
+static inline gboolean
+uri_exists (const char *uri)
+{
+ GFile *file = g_file_new_for_uri (uri);
+ if (file != NULL) {
+ if (g_file_query_exists (file, NULL)) {
+ g_object_unref (file);
+ return TRUE;
+ }
+ g_object_unref (file);
+ }
+ return FALSE;
+}
+
+static char *
+uri_get_subtitle_for_uri (const char *uri)
+{
+ char *subtitle;
+ guint len, i;
+ gint suffix;
+
+ /* Find the filename suffix delimiter */
+ len = strlen (uri);
+ for (suffix = len - 1; suffix > 0; suffix--) {
+ if (uri[suffix] == G_DIR_SEPARATOR ||
+ (uri[suffix] == '/')) {
+ /* This filename has no extension; we'll need to
+ * add one */
+ suffix = len;
+ break;
+ }
+ if (uri[suffix] == '.') {
+ /* Found our extension marker */
+ break;
+ }
+ }
+ if (suffix < 0)
+ return NULL;
+
+ /* Generate a subtitle string with room at the end to store the
+ * 3 character extensions for which we want to search */
+ subtitle = g_malloc0 (suffix + 4 + 1);
+ g_return_val_if_fail (subtitle != NULL, NULL);
+ g_strlcpy (subtitle, uri, suffix + 4 + 1);
+ g_strlcpy (subtitle + suffix, ".???", 5);
+
+ /* Search for any files with one of our known subtitle extensions */
+ for (i = 0; i < G_N_ELEMENTS (subtitle_ext) ; i++) {
+ char *subtitle_ext_upper;
+ memcpy (subtitle + suffix + 1, subtitle_ext[i], 3);
+
+ if (uri_exists (subtitle))
+ return subtitle;
+
+ /* Check with upper-cased extension */
+ subtitle_ext_upper = g_ascii_strup (subtitle_ext[i], -1);
+ memcpy (subtitle + suffix + 1, subtitle_ext_upper, 3);
+ g_free (subtitle_ext_upper);
+
+ if (uri_exists (subtitle))
+ return subtitle;
+ }
+ g_free (subtitle);
+ return NULL;
+}
+
+static char *
+uri_get_subtitle_in_subdir (GFile *file, const char *subdir)
+{
+ char *filename, *subtitle, *full_path_str;
+ GFile *parent, *full_path, *directory;
+
+ /* Get the sibling directory @subdir of the file @file */
+ parent = g_file_get_parent (file);
+ directory = g_file_get_child (parent, subdir);
+ g_object_unref (parent);
+
+ /* Get the file of the same name as @file in the @subdir directory */
+ filename = g_file_get_basename (file);
+ full_path = g_file_get_child (directory, filename);
+ g_object_unref (directory);
+ g_free (filename);
+
+ /* Get the subtitles from that URI */
+ full_path_str = g_file_get_uri (full_path);
+ g_object_unref (full_path);
+ subtitle = uri_get_subtitle_for_uri (full_path_str);
+ g_free (full_path_str);
+
+ return subtitle;
+}
+
+char *
+uri_get_subtitle_uri (const char *uri)
+{
+ GFile *file;
+ char *subtitle;
+
+ if (g_str_has_prefix (uri, "http") != FALSE)
+ return NULL;
+
+ /* Has the user specified a subtitle file manually? */
+ if (strstr (uri, "#subtitle:") != NULL)
+ return NULL;
+
+ /* Does the file exist? */
+ file = g_file_new_for_uri (uri);
+ if (g_file_query_exists (file, NULL) != TRUE) {
+ g_object_unref (file);
+ return NULL;
+ }
+
+ /* Try in the current directory */
+ subtitle = uri_get_subtitle_for_uri (uri);
+ if (subtitle != NULL) {
+ g_object_unref (file);
+ return subtitle;
+ }
+
+ subtitle = uri_get_subtitle_in_subdir (file, "subtitles");
+ g_object_unref (file);
+
+ return subtitle;
+}
+
+/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef MAFW_GST_RENDERER_UTILS_H
+#define MAFW_GST_RENDERER_UTILS_H
+
+G_BEGIN_DECLS
+
+gboolean convert_utf8(const gchar *src, gchar **dst);
+gboolean uri_is_playlist(const gchar *uri);
+gboolean uri_is_stream(const gchar *uri);
+
+char *uri_get_subtitle_uri(const char *uri);
+
+G_END_DECLS
+#endif
+/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME
+
+#include <pulse/pulseaudio.h>
+#include <pulse/glib-mainloop.h>
+#include <pulse/ext-stream-restore.h>
+#include <string.h>
+
+#include "mafw-gst-renderer-worker-volume.h"
+#include "config.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-worker-volume"
+
+#define MAFW_GST_RENDERER_WORKER_VOLUME_SERVER NULL
+
+#define MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PROPERTY "PULSE_PROP_media.role"
+#define MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX "sink-input-by-media-role:"
+#define MAFW_GST_RENDERER_WORKER_VOLUME_ROLE "x-maemo"
+
+#define MAFW_GST_RENDERER_WORKER_SET_TIMEOUT 200
+
+
+struct _MafwGstRendererWorkerVolume {
+ pa_glib_mainloop *mainloop;
+ pa_context *context;
+ gdouble pulse_volume;
+ gboolean pulse_mute;
+ MafwGstRendererWorkerVolumeChangedCb cb;
+ gpointer user_data;
+ MafwGstRendererWorkerVolumeMuteCb mute_cb;
+ gpointer mute_user_data;
+ gdouble current_volume;
+ gboolean current_mute;
+ gboolean pending_operation;
+ gdouble pending_operation_volume;
+ gboolean pending_operation_mute;
+ guint change_request_id;
+ pa_operation *pa_operation;
+};
+
+typedef struct {
+ MafwGstRendererWorkerVolume *wvolume;
+ MafwGstRendererWorkerVolumeInitCb cb;
+ gpointer user_data;
+} InitCbClosure;
+
+#define _pa_volume_to_per_one(volume) \
+ ((guint) ((((gdouble)(volume) / (gdouble) PA_VOLUME_NORM) + \
+ (gdouble) 0.005) * (gdouble) 100.0) / (gdouble) 100.0)
+#define _pa_volume_from_per_one(volume) \
+ ((pa_volume_t)((gdouble)(volume) * (gdouble) PA_VOLUME_NORM))
+
+#define _pa_operation_running(wvolume) \
+ (wvolume->pa_operation != NULL && \
+ pa_operation_get_state(wvolume->pa_operation) == PA_OPERATION_RUNNING)
+
+static void _state_cb_init(pa_context *c, void *data);
+
+
+static gchar *_get_client_name(void) {
+ gchar buf[PATH_MAX];
+ gchar *name = NULL;
+
+ if (pa_get_binary_name(buf, sizeof(buf)))
+ name = g_strdup_printf("mafw-gst-renderer[%s]", buf);
+ else
+ name = g_strdup("mafw-gst-renderer");
+
+ return name;
+}
+
+static void _ext_stream_restore_read_cb(pa_context *c,
+ const pa_ext_stream_restore2_info *i,
+ int eol,
+ void *userdata)
+{
+ MafwGstRendererWorkerVolume *wvolume = userdata;
+ gdouble volume;
+ gboolean mute;
+
+ if (eol < 0) {
+ g_critical("eol parameter should not be < 1. "
+ "Discarding volume event");
+ return;
+ }
+
+ if (i == NULL ||
+ strcmp(i->name, MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX
+ MAFW_GST_RENDERER_WORKER_VOLUME_ROLE) != 0) {
+ return;
+ }
+
+ volume = _pa_volume_to_per_one(pa_cvolume_max(&i->volume));
+ mute = i->mute != 0 ? TRUE : FALSE;
+
+ if (_pa_operation_running(wvolume) ||
+ (wvolume->pending_operation &&
+ (wvolume->pending_operation_volume != volume
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+ || wvolume->pending_operation_mute != mute
+#endif
+ ))) {
+ g_debug("volume notification, but operation running, ignoring");
+ return;
+ }
+
+ wvolume->pulse_volume = volume;
+ wvolume->pulse_mute = mute;
+
+ /* EMIT VOLUME */
+ g_debug("ext stream volume is %lf (mute: %d) for role %s in device %s",
+ wvolume->pulse_volume, wvolume->pulse_mute, i->name, i->device);
+ if (!wvolume->pending_operation &&
+ wvolume->pulse_volume != wvolume->current_volume) {
+ wvolume->current_volume = wvolume->pulse_volume;
+ if (wvolume->cb != NULL) {
+ g_debug("signalling volume");
+ wvolume->cb(wvolume, wvolume->current_volume,
+ wvolume->user_data);
+ }
+ }
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+ if (!wvolume->pending_operation &&
+ wvolume->pulse_mute != wvolume->current_mute) {
+ wvolume->current_mute = wvolume->pulse_mute;
+ if (wvolume->mute_cb != NULL) {
+ g_debug("signalling mute");
+ wvolume->mute_cb(wvolume, wvolume->current_mute,
+ wvolume->mute_user_data);
+ }
+ }
+#endif
+
+ wvolume->pending_operation = FALSE;
+}
+
+static void _destroy_context(MafwGstRendererWorkerVolume *wvolume)
+{
+ if (wvolume->pa_operation != NULL) {
+ if (pa_operation_get_state(wvolume->pa_operation) ==
+ PA_OPERATION_RUNNING) {
+ pa_operation_cancel(wvolume->pa_operation);
+ }
+ pa_operation_unref(wvolume->pa_operation);
+ wvolume->pa_operation = NULL;
+ }
+ pa_context_unref(wvolume->context);
+}
+
+static InitCbClosure *_init_cb_closure_new(MafwGstRendererWorkerVolume *wvolume,
+ MafwGstRendererWorkerVolumeInitCb cb,
+ gpointer user_data)
+{
+ InitCbClosure *closure;
+
+ closure = g_new(InitCbClosure, 1);
+ closure->wvolume = wvolume;
+ closure->cb = cb;
+ closure->user_data = user_data;
+
+ return closure;
+}
+
+static void _connect(gpointer user_data)
+{
+ gchar *name = NULL;
+ pa_mainloop_api *api = NULL;
+ InitCbClosure *closure = user_data;
+ MafwGstRendererWorkerVolume *wvolume = closure->wvolume;
+
+ name = _get_client_name();
+
+ /* get the mainloop api and create a context */
+ api = pa_glib_mainloop_get_api(wvolume->mainloop);
+ wvolume->context = pa_context_new(api, name);
+ g_assert(wvolume->context != NULL);
+
+ /* register some essential callbacks */
+ pa_context_set_state_callback(wvolume->context, _state_cb_init,
+ closure);
+
+ g_debug("connecting to pulse");
+
+ g_assert(pa_context_connect(wvolume->context,
+ MAFW_GST_RENDERER_WORKER_VOLUME_SERVER,
+ PA_CONTEXT_NOAUTOSPAWN | PA_CONTEXT_NOFAIL,
+ NULL) >= 0);
+ g_free(name);
+}
+
+static gboolean _reconnect(gpointer user_data)
+{
+ InitCbClosure *closure = user_data;
+ MafwGstRendererWorkerVolume *wvolume = closure->wvolume;
+
+ g_warning("got disconnected from pulse, reconnecting");
+ _destroy_context(wvolume);
+ _connect(user_data);
+
+ return FALSE;
+}
+
+static void
+_state_cb(pa_context *c, void *data)
+{
+ MafwGstRendererWorkerVolume *wvolume = data;
+ pa_context_state_t state;
+
+ state = pa_context_get_state(c);
+
+ switch (state) {
+ case PA_CONTEXT_TERMINATED:
+ case PA_CONTEXT_FAILED:
+ {
+ InitCbClosure *closure;
+
+ closure = _init_cb_closure_new(wvolume, NULL, NULL);
+ g_idle_add(_reconnect, closure);
+ break;
+ }
+ case PA_CONTEXT_READY: {
+ pa_operation *o;
+
+ o = pa_ext_stream_restore2_read(c, _ext_stream_restore_read_cb,
+ wvolume);
+ g_assert(o != NULL);
+ pa_operation_unref(o);
+
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void _ext_stream_restore_read_cb_init(pa_context *c,
+ const pa_ext_stream_restore2_info *i,
+ int eol,
+ void *userdata)
+{
+ InitCbClosure *closure = userdata;
+
+ if (eol < 0) {
+ g_critical("eol parameter should not be < 1");
+ }
+
+ if (i == NULL ||
+ strcmp(i->name, MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX
+ MAFW_GST_RENDERER_WORKER_VOLUME_ROLE) != 0)
+ return;
+
+ closure->wvolume->pulse_volume =
+ _pa_volume_to_per_one(pa_cvolume_max(&i->volume));
+ closure->wvolume->pulse_mute = i->mute != 0 ? TRUE : FALSE;
+ closure->wvolume->current_volume = closure->wvolume->pulse_volume;
+ closure->wvolume->current_mute = closure->wvolume->pulse_mute;
+
+ /* NOT EMIT VOLUME, BUT DEBUG */
+ g_debug("ext stream volume is %lf (mute: %d) for role %s in device %s",
+ closure->wvolume->pulse_volume, i->mute, i->name, i->device);
+
+ if (closure->cb != NULL) {
+ g_debug("initialized: returning volume manager");
+ closure->cb(closure->wvolume, closure->user_data);
+ } else {
+ if (closure->wvolume->cb != NULL) {
+ g_debug("signalling volume after reconnection");
+ closure->wvolume->cb(closure->wvolume,
+ closure->wvolume->current_volume,
+ closure->wvolume->user_data);
+ }
+ if (closure->wvolume->mute_cb != NULL) {
+ g_debug("signalling mute after reconnection");
+ closure->wvolume->mute_cb(closure->wvolume,
+ closure->wvolume->
+ current_mute,
+ closure->wvolume->
+ mute_user_data);
+ }
+ }
+
+ pa_context_set_state_callback(closure->wvolume->context, _state_cb,
+ closure->wvolume);
+
+ g_free(closure);
+}
+
+static void _ext_stream_restore_subscribe_cb(pa_context *c, void *userdata)
+{
+ pa_operation *o;
+
+ o = pa_ext_stream_restore2_read(c, _ext_stream_restore_read_cb, userdata);
+ g_assert(o != NULL);
+ pa_operation_unref(o);
+}
+
+static void
+_state_cb_init(pa_context *c, void *data)
+{
+ InitCbClosure *closure = data;
+ MafwGstRendererWorkerVolume *wvolume = closure->wvolume;
+ pa_context_state_t state;
+
+ state = pa_context_get_state(c);
+
+ g_debug("state: %d", state);
+
+ switch (state) {
+ case PA_CONTEXT_TERMINATED:
+ case PA_CONTEXT_FAILED:
+ g_critical("Connection to pulse failed, reconnection in 1 "
+ "second");
+ g_timeout_add_seconds(1, _reconnect, closure);
+ break;
+ case PA_CONTEXT_READY: {
+ pa_operation *o;
+
+ g_debug("PA_CONTEXT_READY");
+
+ o = pa_ext_stream_restore2_read(c,
+ _ext_stream_restore_read_cb_init,
+ closure);
+ g_assert(o != NULL);
+ pa_operation_unref(o);
+
+ pa_ext_stream_restore_set_subscribe_cb(
+ c, _ext_stream_restore_subscribe_cb, wvolume);
+
+ o = pa_ext_stream_restore_subscribe(c, 1, NULL, NULL);
+ g_assert(o != NULL);
+ pa_operation_unref(o);
+
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static gboolean _destroy_idle(gpointer data)
+{
+ MafwGstRendererWorkerVolume *wvolume = data;
+
+ g_debug("destroying");
+
+ _destroy_context(wvolume);
+ pa_glib_mainloop_free(wvolume->mainloop);
+ g_free(wvolume);
+
+ return FALSE;
+}
+
+static void
+_state_cb_destroy(pa_context *c, void *data)
+{
+ pa_context_state_t state;
+
+ state = pa_context_get_state(c);
+
+ switch (state) {
+ case PA_CONTEXT_TERMINATED:
+ g_idle_add(_destroy_idle, data);
+ break;
+ case PA_CONTEXT_FAILED:
+ g_error("Unexpected problem in volume management");
+ break;
+ default:
+ break;
+ }
+}
+
+static void _success_cb(pa_context *c, int success, void *userdata)
+{
+ if (success == 0) {
+ g_critical("Setting volume to pulse operation failed");
+ }
+}
+
+static void _remove_set_timeout(MafwGstRendererWorkerVolume *wvolume)
+{
+ if (wvolume->change_request_id != 0) {
+ g_source_remove(wvolume->change_request_id);
+ }
+ wvolume->change_request_id = 0;
+}
+
+static gboolean _set_timeout(gpointer data)
+{
+ pa_ext_stream_restore2_info info;
+ pa_ext_stream_restore2_info *infos[1];
+ MafwGstRendererWorkerVolume *wvolume = data;
+
+ if (wvolume->pending_operation) {
+ g_debug("setting volume ignored as there is still a pending "
+ "operation. Waiting till next iteration");
+ } else if (wvolume->pulse_volume != wvolume->current_volume
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+ || wvolume->pulse_mute != wvolume->current_mute
+#endif
+ ) {
+
+ info.name = MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX
+ MAFW_GST_RENDERER_WORKER_VOLUME_ROLE;
+ info.channel_map.channels = 1;
+ info.channel_map.map[0] = PA_CHANNEL_POSITION_MONO;
+ info.device = NULL;
+ info.volume_is_absolute = TRUE;
+ infos[0] = &info;
+
+ info.mute = wvolume->current_mute;
+ pa_cvolume_init(&info.volume);
+ pa_cvolume_set(&info.volume, info.channel_map.channels,
+ _pa_volume_from_per_one(wvolume->
+ current_volume));
+
+ g_debug("setting volume to %lf and mute to %d",
+ wvolume->current_volume, wvolume->current_mute);
+
+ if (wvolume->pa_operation != NULL) {
+ pa_operation_unref(wvolume->pa_operation);
+ }
+
+ wvolume->pending_operation = TRUE;
+ wvolume->pending_operation_volume = wvolume->current_volume;
+ wvolume->pending_operation_mute = wvolume->current_mute;
+
+ wvolume->pa_operation = pa_ext_stream_restore2_write(
+ wvolume->context,
+ PA_UPDATE_REPLACE,
+ (const pa_ext_stream_restore2_info*
+ const *)infos,
+ 1, TRUE, _success_cb, wvolume);
+
+ if (wvolume->pa_operation == NULL) {
+ g_critical("NULL operation when writing volume to "
+ "pulse");
+ _remove_set_timeout(wvolume);
+ }
+ } else {
+ g_debug("removing volume timeout");
+ _remove_set_timeout(wvolume);
+ }
+
+ return wvolume->change_request_id != 0;
+}
+
+void mafw_gst_renderer_worker_volume_init(GMainContext *main_context,
+ MafwGstRendererWorkerVolumeInitCb cb,
+ gpointer user_data,
+ MafwGstRendererWorkerVolumeChangedCb
+ changed_cb,
+ gpointer changed_user_data,
+ MafwGstRendererWorkerVolumeMuteCb
+ mute_cb, gpointer mute_user_data)
+{
+ MafwGstRendererWorkerVolume *wvolume = NULL;
+ InitCbClosure *closure;
+
+ g_return_if_fail(cb != NULL);
+
+ g_assert(g_setenv(MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PROPERTY,
+ MAFW_GST_RENDERER_WORKER_VOLUME_ROLE, FALSE));
+
+ g_debug("initializing volume manager");
+
+ wvolume = g_new0(MafwGstRendererWorkerVolume, 1);
+
+ wvolume->pulse_volume = 1.0;
+ wvolume->pulse_mute = FALSE;
+ wvolume->cb = changed_cb;
+ wvolume->user_data = changed_user_data;
+ wvolume->mute_cb = mute_cb;
+ wvolume->mute_user_data = mute_user_data;
+
+ wvolume->mainloop = pa_glib_mainloop_new(main_context);
+ g_assert(wvolume->mainloop != NULL);
+
+ closure = _init_cb_closure_new(wvolume, cb, user_data);
+ _connect(closure);
+}
+
+void mafw_gst_renderer_worker_volume_set(MafwGstRendererWorkerVolume *wvolume,
+ gdouble volume, gboolean mute)
+{
+ gboolean signal_volume, signal_mute;
+
+ g_return_if_fail(wvolume != NULL);
+ g_return_if_fail(pa_context_get_state(wvolume->context) ==
+ PA_CONTEXT_READY);
+
+#ifndef MAFW_GST_RENDERER_ENABLE_MUTE
+ mute = FALSE;
+#endif
+
+ signal_volume = wvolume->current_volume != volume &&
+ wvolume->cb != NULL;
+ signal_mute = wvolume->current_mute != mute && wvolume->mute_cb != NULL;
+
+ wvolume->current_volume = volume;
+ wvolume->current_mute = mute;
+
+ g_debug("volume set: %lf (mute %d)", volume, mute);
+
+ if (signal_volume) {
+ g_debug("signalling volume");
+ wvolume->cb(wvolume, volume, wvolume->user_data);
+ }
+
+ if (signal_mute) {
+ g_debug("signalling mute");
+ wvolume->mute_cb(wvolume, mute, wvolume->mute_user_data);
+ }
+
+ if ((signal_mute || signal_volume) && wvolume->change_request_id == 0) {
+ wvolume->change_request_id =
+ g_timeout_add(MAFW_GST_RENDERER_WORKER_SET_TIMEOUT,
+ _set_timeout, wvolume);
+
+ _set_timeout(wvolume);
+ }
+}
+
+gdouble mafw_gst_renderer_worker_volume_get(
+ MafwGstRendererWorkerVolume *wvolume)
+{
+ g_return_val_if_fail(wvolume != NULL, 0.0);
+
+ g_debug("getting volume; %lf", wvolume->current_volume);
+
+ return wvolume->current_volume;
+}
+
+gboolean mafw_gst_renderer_worker_volume_is_muted(
+ MafwGstRendererWorkerVolume *wvolume)
+{
+ g_return_val_if_fail(wvolume != NULL, FALSE);
+
+ g_debug("getting mute; %d", wvolume->current_mute);
+
+ return wvolume->current_mute;
+}
+
+void mafw_gst_renderer_worker_volume_destroy(
+ MafwGstRendererWorkerVolume *wvolume)
+{
+ g_return_if_fail(wvolume != NULL);
+
+ g_debug("disconnecting");
+
+ pa_ext_stream_restore_set_subscribe_cb(wvolume->context, NULL, NULL);
+ pa_context_set_state_callback(wvolume->context, _state_cb_destroy,
+ wvolume);
+ pa_context_disconnect(wvolume->context);
+}
+
+
+
+#else
+
+
+#include "mafw-gst-renderer-worker-volume.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-worker-volume-fake"
+
+struct _MafwGstRendererWorkerVolume {
+ MafwGstRendererWorkerVolumeChangedCb cb;
+ gpointer user_data;
+ MafwGstRendererWorkerVolumeMuteCb mute_cb;
+ gpointer mute_user_data;
+ gdouble current_volume;
+ gboolean current_mute;
+};
+
+typedef struct {
+ MafwGstRendererWorkerVolume *wvolume;
+ MafwGstRendererWorkerVolumeInitCb cb;
+ gpointer user_data;
+} InitCbClosure;
+
+static gboolean _init_cb_closure(gpointer user_data)
+{
+ InitCbClosure *closure = user_data;
+
+ if (closure->cb != NULL) {
+ closure->cb(closure->wvolume, closure->user_data);
+ }
+ g_free(closure);
+
+ return FALSE;
+}
+
+void mafw_gst_renderer_worker_volume_init(GMainContext *main_context,
+ MafwGstRendererWorkerVolumeInitCb cb,
+ gpointer user_data,
+ MafwGstRendererWorkerVolumeChangedCb
+ changed_cb,
+ gpointer changed_user_data,
+ MafwGstRendererWorkerVolumeMuteCb
+ mute_cb, gpointer mute_user_data)
+{
+ MafwGstRendererWorkerVolume *wvolume = NULL;
+ InitCbClosure *closure;
+
+ g_return_if_fail(cb != NULL);
+
+ g_debug("initializing volume manager");
+
+ wvolume = g_new0(MafwGstRendererWorkerVolume, 1);
+
+ wvolume->cb = changed_cb;
+ wvolume->user_data = changed_user_data;
+ wvolume->mute_cb = mute_cb;
+ wvolume->mute_user_data = mute_user_data;
+ wvolume->current_volume = 0.485;
+
+ closure = g_new0(InitCbClosure, 1);
+ closure->wvolume = wvolume;
+ closure->cb = cb;
+ closure->user_data = user_data;
+ g_idle_add(_init_cb_closure, closure);
+}
+
+void mafw_gst_renderer_worker_volume_set(MafwGstRendererWorkerVolume *wvolume,
+ gdouble volume, gboolean mute)
+{
+ gboolean signal_volume, signal_mute;
+
+ g_return_if_fail(wvolume != NULL);
+
+#ifndef MAFW_GST_RENDERER_ENABLE_MUTE
+ mute = FALSE;
+#endif
+
+ signal_volume = wvolume->current_volume != volume &&
+ wvolume->cb != NULL;
+ signal_mute = wvolume->current_mute != mute && wvolume->mute_cb != NULL;
+
+ wvolume->current_volume = volume;
+ wvolume->current_mute = mute;
+
+ g_debug("volume set: %lf (mute %d)", volume, mute);
+
+ if (signal_volume) {
+ g_debug("signalling volume");
+ wvolume->cb(wvolume, volume, wvolume->user_data);
+ }
+
+ if (signal_mute) {
+ g_debug("signalling mute");
+ wvolume->mute_cb(wvolume, mute, wvolume->mute_user_data);
+ }
+}
+
+gdouble mafw_gst_renderer_worker_volume_get(
+ MafwGstRendererWorkerVolume *wvolume)
+{
+ g_return_val_if_fail(wvolume != NULL, 0.0);
+
+ g_debug("getting volume; %lf", wvolume->current_volume);
+
+ return wvolume->current_volume;
+}
+
+gboolean mafw_gst_renderer_worker_volume_is_muted(
+ MafwGstRendererWorkerVolume *wvolume)
+{
+ g_return_val_if_fail(wvolume != NULL, FALSE);
+
+ g_debug("getting mute; %d", wvolume->current_mute);
+
+ return wvolume->current_mute;
+}
+
+void mafw_gst_renderer_worker_volume_destroy(
+ MafwGstRendererWorkerVolume *wvolume)
+{
+ g_return_if_fail(wvolume != NULL);
+
+ g_free(wvolume);
+}
+
+#endif
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef MAFW_GST_RENDERER_WORKER_VOLUME_H
+#define MAFW_GST_RENDERER_WORKER_VOLUME_H
+
+#include <glib.h>
+
+typedef struct _MafwGstRendererWorkerVolume MafwGstRendererWorkerVolume;
+
+typedef void(*MafwGstRendererWorkerVolumeChangedCb)(
+ MafwGstRendererWorkerVolume *wvolume, gdouble volume, gpointer data);
+
+typedef void(*MafwGstRendererWorkerVolumeMuteCb)(
+ MafwGstRendererWorkerVolume *wvolume, gboolean mute, gpointer data);
+
+typedef void(*MafwGstRendererWorkerVolumeInitCb)(
+ MafwGstRendererWorkerVolume *volume, gpointer data);
+
+G_BEGIN_DECLS
+
+void mafw_gst_renderer_worker_volume_init(GMainContext *main_context,
+ MafwGstRendererWorkerVolumeInitCb cb,
+ gpointer user_data,
+ MafwGstRendererWorkerVolumeChangedCb
+ changed_cb,
+ gpointer changed_user_data,
+ MafwGstRendererWorkerVolumeMuteCb
+ mute_cb, gpointer mute_user_data);
+
+void mafw_gst_renderer_worker_volume_set(MafwGstRendererWorkerVolume *wvolume,
+ gdouble volume, gboolean mute);
+
+gdouble mafw_gst_renderer_worker_volume_get(
+ MafwGstRendererWorkerVolume *wvolume);
+gboolean mafw_gst_renderer_worker_volume_is_muted(
+ MafwGstRendererWorkerVolume *wvolume);
+
+void mafw_gst_renderer_worker_volume_destroy(
+ MafwGstRendererWorkerVolume *wvolume);
+
+G_END_DECLS
+#endif
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <glib.h>
+#include <X11/Xlib.h>
+#include <gst/interfaces/xoverlay.h>
+#include <gst/pbutils/missing-plugins.h>
+#include <gst/base/gstbasesink.h>
+#include <libmafw/mafw.h>
+
+#ifdef HAVE_GDKPIXBUF
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <glib/gstdio.h>
+#include <unistd.h>
+#include "gstscreenshot.h"
+#endif
+
+#include <totem-pl-parser.h>
+#include "mafw-gst-renderer.h"
+#include "mafw-gst-renderer-worker.h"
+#include "mafw-gst-renderer-utils.h"
+#include "blanking.h"
+#include "keypad.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-worker"
+
+#define MAFW_GST_RENDERER_WORKER_SECONDS_READY 60
+#define MAFW_GST_RENDERER_WORKER_SECONDS_DURATION_AND_SEEKABILITY 4
+
+#define MAFW_GST_MISSING_TYPE_DECODER "decoder"
+#define MAFW_GST_MISSING_TYPE_ENCODER "encoder"
+
+#define MAFW_GST_BUFFER_TIME 600000L
+#define MAFW_GST_LATENCY_TIME (MAFW_GST_BUFFER_TIME / 2)
+
+#define NSECONDS_TO_SECONDS(ns) ((ns)%1000000000 < 500000000?\
+ GST_TIME_AS_SECONDS((ns)):\
+ GST_TIME_AS_SECONDS((ns))+1)
+
+#define _current_metadata_add(worker, key, type, value) \
+ do { \
+ if (!worker->current_metadata) \
+ worker->current_metadata = mafw_metadata_new(); \
+ /* At first remove old value */ \
+ g_hash_table_remove(worker->current_metadata, key); \
+ mafw_metadata_add_something(worker->current_metadata, \
+ key, type, 1, value); \
+ } while (0)
+
+/* Private variables. */
+/* Global reference to worker instance, needed for Xerror handler */
+static MafwGstRendererWorker *Global_worker = NULL;
+
+/* Forward declarations. */
+static void _do_play(MafwGstRendererWorker *worker);
+static void _do_seek(MafwGstRendererWorker *worker, GstSeekType seek_type,
+ gint position, GError **error);
+static void _play_pl_next(MafwGstRendererWorker *worker);
+
+static void _emit_metadatas(MafwGstRendererWorker *worker);
+
+/* Playlist parsing */
+static void _on_pl_entry_parsed(TotemPlParser *parser, gchar *uri,
+ gpointer metadata, GSList **plitems)
+{
+ if (uri != NULL) {
+ *plitems = g_slist_append(*plitems, g_strdup(uri));
+ }
+}
+static GSList *_parse_playlist(const gchar *uri)
+{
+ static TotemPlParser *pl_parser = NULL;
+ GSList *plitems = NULL;
+ gulong handler_id;
+
+ /* Initialize the playlist parser */
+ if (!pl_parser)
+ {
+ pl_parser = totem_pl_parser_new ();
+ g_object_set(pl_parser, "recurse", TRUE, "disable-unsafe",
+ TRUE, NULL);
+ }
+ handler_id = g_signal_connect(G_OBJECT(pl_parser), "entry-parsed",
+ G_CALLBACK(_on_pl_entry_parsed), &plitems);
+ /* Parsing */
+ if (totem_pl_parser_parse(pl_parser, uri, FALSE) !=
+ TOTEM_PL_PARSER_RESULT_SUCCESS) {
+ /* An error happens while parsing */
+
+ }
+ g_signal_handler_disconnect(pl_parser, handler_id);
+ return plitems;
+}
+
+/*
+ * Sends @error to MafwGstRenderer. Only call this from the glib main thread, or
+ * face the consequences. @err is free'd.
+ */
+static void _send_error(MafwGstRendererWorker *worker, GError *err)
+{
+ worker->is_error = TRUE;
+ if (worker->notify_error_handler)
+ worker->notify_error_handler(worker, worker->owner, err);
+ g_error_free(err);
+}
+
+/*
+ * Posts an @error on the gst bus. _async_bus_handler will then pick it up and
+ * forward to MafwGstRenderer. @err is free'd.
+ */
+static void _post_error(MafwGstRendererWorker *worker, GError *err)
+{
+ gst_bus_post(worker->bus,
+ gst_message_new_error(GST_OBJECT(worker->pipeline),
+ err, NULL));
+ g_error_free(err);
+}
+
+#ifdef HAVE_GDKPIXBUF
+typedef struct {
+ MafwGstRendererWorker *worker;
+ gchar *metadata_key;
+ GdkPixbuf *pixbuf;
+} SaveGraphicData;
+
+static gchar *_init_tmp_file(void)
+{
+ gint fd;
+ gchar *path = NULL;
+
+ fd = g_file_open_tmp("mafw-gst-renderer-XXXXXX.jpeg", &path, NULL);
+ close(fd);
+
+ return path;
+}
+
+static void _init_tmp_files_pool(MafwGstRendererWorker *worker)
+{
+ guint8 i;
+
+ worker->tmp_files_pool_index = 0;
+
+ for (i = 0; i < MAFW_GST_RENDERER_MAX_TMP_FILES; i++) {
+ worker->tmp_files_pool[i] = NULL;
+ }
+}
+
+static void _destroy_tmp_files_pool(MafwGstRendererWorker *worker)
+{
+ guint8 i;
+
+ for (i = 0; (i < MAFW_GST_RENDERER_MAX_TMP_FILES) &&
+ (worker->tmp_files_pool[i] != NULL); i++) {
+ g_unlink(worker->tmp_files_pool[i]);
+ g_free(worker->tmp_files_pool[i]);
+ }
+}
+
+static const gchar *_get_tmp_file_from_pool(
+ MafwGstRendererWorker *worker)
+{
+ gchar *path = worker->tmp_files_pool[worker->tmp_files_pool_index];
+
+ if (path == NULL) {
+ path = _init_tmp_file();
+ worker->tmp_files_pool[worker->tmp_files_pool_index] = path;
+ }
+
+ if (++(worker->tmp_files_pool_index) >=
+ MAFW_GST_RENDERER_MAX_TMP_FILES) {
+ worker->tmp_files_pool_index = 0;
+ }
+
+ return path;
+}
+
+static void _destroy_pixbuf (guchar *pixbuf, gpointer data)
+{
+ gst_buffer_unref(GST_BUFFER(data));
+}
+
+static void _emit_gst_buffer_as_graphic_file_cb(GstBuffer *new_buffer,
+ gpointer user_data)
+{
+ SaveGraphicData *sgd = user_data;
+ GdkPixbuf *pixbuf = NULL;
+
+ if (new_buffer != NULL) {
+ gint width, height;
+ GstStructure *structure;
+
+ structure =
+ gst_caps_get_structure(GST_BUFFER_CAPS(new_buffer), 0);
+
+ gst_structure_get_int(structure, "width", &width);
+ gst_structure_get_int(structure, "height", &height);
+
+ pixbuf = gdk_pixbuf_new_from_data(
+ GST_BUFFER_DATA(new_buffer), GDK_COLORSPACE_RGB,
+ FALSE, 8, width, height,
+ GST_ROUND_UP_4(3 * width), _destroy_pixbuf,
+ new_buffer);
+
+ if (sgd->pixbuf != NULL) {
+ g_object_unref(sgd->pixbuf);
+ sgd->pixbuf = NULL;
+ }
+ } else {
+ pixbuf = sgd->pixbuf;
+ }
+
+ if (pixbuf != NULL) {
+ gboolean save_ok;
+ GError *error = NULL;
+ const gchar *filename;
+
+ filename = _get_tmp_file_from_pool(sgd->worker);
+
+ save_ok = gdk_pixbuf_save (pixbuf, filename, "jpeg", &error,
+ NULL);
+
+ g_object_unref (pixbuf);
+
+ if (save_ok) {
+ /* Add the info to the current metadata. */
+ _current_metadata_add(sgd->worker, sgd->metadata_key,
+ G_TYPE_STRING,
+ (gchar*)filename);
+
+ /* Emit the metadata. */
+ mafw_renderer_emit_metadata_string(sgd->worker->owner,
+ sgd->metadata_key,
+ (gchar *) filename);
+ } else {
+ if (error != NULL) {
+ g_warning ("%s\n", error->message);
+ g_error_free (error);
+ } else {
+ g_critical("Unknown error when saving pixbuf "
+ "with GStreamer data");
+ }
+ }
+ } else {
+ g_warning("Could not create pixbuf from GstBuffer");
+ }
+
+ g_free(sgd->metadata_key);
+ g_free(sgd);
+}
+
+static void _pixbuf_size_prepared_cb (GdkPixbufLoader *loader,
+ gint width, gint height,
+ gpointer user_data)
+{
+ /* Be sure the image size is reasonable */
+ if (width > 512 || height > 512) {
+ g_debug ("pixbuf: image is too big: %dx%d", width, height);
+ gdouble ar;
+ ar = (gdouble) width / height;
+ if (width > height) {
+ width = 512;
+ height = width / ar;
+ } else {
+ height = 512;
+ width = height * ar;
+ }
+ g_debug ("pixbuf: scaled image to %dx%d", width, height);
+ gdk_pixbuf_loader_set_size (loader, width, height);
+ }
+}
+
+static void _emit_gst_buffer_as_graphic_file(MafwGstRendererWorker *worker,
+ GstBuffer *buffer,
+ const gchar *metadata_key)
+{
+ GdkPixbufLoader *loader;
+ GstStructure *structure;
+ const gchar *mime = NULL;
+ GError *error = NULL;
+
+ g_return_if_fail((buffer != NULL) && GST_IS_BUFFER(buffer));
+
+ structure = gst_caps_get_structure(GST_BUFFER_CAPS(buffer), 0);
+ mime = gst_structure_get_name(structure);
+
+ if (g_str_has_prefix(mime, "video/x-raw")) {
+ gint framerate_d, framerate_n;
+ GstCaps *to_caps;
+ SaveGraphicData *sgd;
+
+ gst_structure_get_fraction (structure, "framerate",
+ &framerate_n, &framerate_d);
+
+ to_caps = gst_caps_new_simple ("video/x-raw-rgb",
+ "bpp", G_TYPE_INT, 24,
+ "depth", G_TYPE_INT, 24,
+ "framerate", GST_TYPE_FRACTION,
+ framerate_n, framerate_d,
+ "pixel-aspect-ratio",
+ GST_TYPE_FRACTION, 1, 1,
+ "endianness",
+ G_TYPE_INT, G_BIG_ENDIAN,
+ "red_mask", G_TYPE_INT,
+ 0xff0000,
+ "green_mask",
+ G_TYPE_INT, 0x00ff00,
+ "blue_mask",
+ G_TYPE_INT, 0x0000ff,
+ NULL);
+
+ sgd = g_new0(SaveGraphicData, 1);
+ sgd->worker = worker;
+ sgd->metadata_key = g_strdup(metadata_key);
+
+ g_debug("pixbuf: using bvw to convert image format");
+ bvw_frame_conv_convert (buffer, to_caps,
+ _emit_gst_buffer_as_graphic_file_cb,
+ sgd);
+ } else {
+ GdkPixbuf *pixbuf = NULL;
+ loader = gdk_pixbuf_loader_new_with_mime_type(mime, &error);
+ g_signal_connect (G_OBJECT (loader), "size-prepared",
+ (GCallback)_pixbuf_size_prepared_cb, NULL);
+
+ if (loader == NULL) {
+ g_warning ("%s\n", error->message);
+ g_error_free (error);
+ } else {
+ if (!gdk_pixbuf_loader_write (loader,
+ GST_BUFFER_DATA(buffer),
+ GST_BUFFER_SIZE(buffer),
+ &error)) {
+ g_warning ("%s\n", error->message);
+ g_error_free (error);
+
+ gdk_pixbuf_loader_close (loader, NULL);
+ } else {
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+ if (!gdk_pixbuf_loader_close (loader, &error)) {
+ g_warning ("%s\n", error->message);
+ g_error_free (error);
+
+ g_object_unref(pixbuf);
+ } else {
+ SaveGraphicData *sgd;
+
+ sgd = g_new0(SaveGraphicData, 1);
+
+ sgd->worker = worker;
+ sgd->metadata_key =
+ g_strdup(metadata_key);
+ sgd->pixbuf = pixbuf;
+
+ _emit_gst_buffer_as_graphic_file_cb(
+ NULL, sgd);
+ }
+ }
+ g_object_unref(loader);
+ }
+ }
+}
+#endif
+
+static gboolean _go_to_gst_ready(gpointer user_data)
+{
+ MafwGstRendererWorker *worker = user_data;
+
+ g_return_val_if_fail(worker->state == GST_STATE_PAUSED ||
+ worker->prerolling, FALSE);
+
+ worker->seek_position =
+ mafw_gst_renderer_worker_get_position(worker);
+
+ g_debug("going to GST_STATE_READY");
+ gst_element_set_state(worker->pipeline, GST_STATE_READY);
+ worker->in_ready = TRUE;
+ worker->ready_timeout = 0;
+
+ return FALSE;
+}
+
+static void _add_ready_timeout(MafwGstRendererWorker *worker)
+{
+ if (worker->media.seekable) {
+ if (!worker->ready_timeout)
+ {
+ g_debug("Adding timeout to go to GST_STATE_READY");
+ worker->ready_timeout =
+ g_timeout_add_seconds(
+ MAFW_GST_RENDERER_WORKER_SECONDS_READY,
+ _go_to_gst_ready,
+ worker);
+ }
+ } else {
+ g_debug("Not adding timeout to go to GST_STATE_READY as media "
+ "is not seekable");
+ worker->ready_timeout = 0;
+ }
+}
+
+static void _remove_ready_timeout(MafwGstRendererWorker *worker)
+{
+ if (worker->ready_timeout != 0) {
+ g_debug("removing timeout for READY");
+ g_source_remove(worker->ready_timeout);
+ worker->ready_timeout = 0;
+ }
+ worker->in_ready = FALSE;
+}
+
+static gboolean _emit_video_info(MafwGstRendererWorker *worker)
+{
+ mafw_renderer_emit_metadata_int(worker->owner,
+ MAFW_METADATA_KEY_RES_X,
+ worker->media.video_width);
+ mafw_renderer_emit_metadata_int(worker->owner,
+ MAFW_METADATA_KEY_RES_Y,
+ worker->media.video_height);
+ mafw_renderer_emit_metadata_double(worker->owner,
+ MAFW_METADATA_KEY_VIDEO_FRAMERATE,
+ worker->media.fps);
+ return FALSE;
+}
+
+/*
+ * Checks if the video details are supported. It also extracts other useful
+ * information (such as PAR and framerate) from the caps, if available. NOTE:
+ * this will be called from a different thread than glib's mainloop (when
+ * invoked via _stream_info_cb); don't call MafwGstRenderer directly.
+ *
+ * Returns: TRUE if video details are acceptable.
+ */
+static gboolean _handle_video_info(MafwGstRendererWorker *worker,
+ const GstStructure *structure)
+{
+ gint width, height;
+ gdouble fps;
+
+ width = height = 0;
+ gst_structure_get_int(structure, "width", &width);
+ gst_structure_get_int(structure, "height", &height);
+ g_debug("video size: %d x %d", width, height);
+ if (gst_structure_has_field(structure, "pixel-aspect-ratio"))
+ {
+ gst_structure_get_fraction(structure, "pixel-aspect-ratio",
+ &worker->media.par_n,
+ &worker->media.par_d);
+ g_debug("video PAR: %d:%d", worker->media.par_n,
+ worker->media.par_d);
+ width = width * worker->media.par_n / worker->media.par_d;
+ }
+
+ fps = 1.0;
+ if (gst_structure_has_field(structure, "framerate"))
+ {
+ gint fps_n, fps_d;
+
+ gst_structure_get_fraction(structure, "framerate",
+ &fps_n, &fps_d);
+ if (fps_d > 0)
+ fps = (gdouble)fps_n / (gdouble)fps_d;
+ g_debug("video fps: %f", fps);
+ }
+
+ worker->media.video_width = width;
+ worker->media.video_height = height;
+ worker->media.fps = fps;
+
+ /* Add the info to the current metadata. */
+ gint p_width, p_height, p_fps;
+
+ p_width = width;
+ p_height = height;
+ p_fps = fps;
+
+ _current_metadata_add(worker, MAFW_METADATA_KEY_RES_X, G_TYPE_INT,
+ p_width);
+ _current_metadata_add(worker, MAFW_METADATA_KEY_RES_Y, G_TYPE_INT,
+ p_height);
+ _current_metadata_add(worker, MAFW_METADATA_KEY_VIDEO_FRAMERATE,
+ G_TYPE_DOUBLE,
+ p_fps);
+
+ /* Emit the metadata.*/
+ g_idle_add((GSourceFunc)_emit_video_info, worker);
+
+ return TRUE;
+}
+
+static void _parse_stream_info_item(MafwGstRendererWorker *worker, GObject *obj)
+{
+ GParamSpec *pspec;
+ GEnumValue *val;
+ gint type;
+
+ g_object_get(obj, "type", &type, NULL);
+ pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), "type");
+ val = g_enum_get_value(G_PARAM_SPEC_ENUM(pspec)->enum_class, type);
+ if (!val)
+ return;
+ if (!g_ascii_strcasecmp(val->value_nick, "video") ||
+ !g_ascii_strcasecmp(val->value_name, "video"))
+ {
+ GstCaps *vcaps;
+ GstObject *object;
+
+ object = NULL;
+ g_object_get(obj, "object", &object, NULL);
+ vcaps = NULL;
+ if (object) {
+ vcaps = gst_pad_get_caps(GST_PAD_CAST(object));
+ } else {
+ g_object_get(obj, "caps", &vcaps, NULL);
+ gst_caps_ref(vcaps);
+ }
+ if (vcaps) {
+ if (gst_caps_is_fixed(vcaps))
+ {
+ _handle_video_info(
+ worker,
+ gst_caps_get_structure(vcaps, 0));
+ }
+ gst_caps_unref(vcaps);
+ }
+ }
+}
+
+/* It always returns FALSE, because it is used as an idle callback as well. */
+static gboolean _parse_stream_info(MafwGstRendererWorker *worker)
+{
+ GList *stream_info, *s;
+
+ stream_info = NULL;
+ if (g_object_class_find_property(G_OBJECT_GET_CLASS(worker->pipeline),
+ "stream-info"))
+ {
+ g_object_get(worker->pipeline,
+ "stream-info", &stream_info, NULL);
+ }
+ for (s = stream_info; s; s = g_list_next(s))
+ _parse_stream_info_item(worker, G_OBJECT(s->data));
+ return FALSE;
+}
+
+static void mafw_gst_renderer_worker_apply_xid(MafwGstRendererWorker *worker)
+{
+ /* Set sink to render on the provided XID if we have do have
+ a XID a valid video sink and we are rendeing video content */
+ if (worker->xid &&
+ worker->vsink &&
+ worker->media.has_visual_content)
+ {
+ g_debug ("Setting overlay, window id: %x",
+ (gint) worker->xid);
+ gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(worker->vsink),
+ worker->xid);
+ /* Ask the gst to redraw the frame if we are paused */
+ /* TODO: in MTG this works only in non-fs -> fs way. */
+ if (worker->state == GST_STATE_PAUSED)
+ {
+ gst_x_overlay_expose(GST_X_OVERLAY(worker->vsink));
+ }
+ } else {
+ g_debug("Not setting overlay for window id: %x",
+ (gint) worker->xid);
+ }
+}
+
+/*
+ * GstBus synchronous message handler. NOTE that this handler is NOT invoked
+ * from the glib thread, so be careful what you do here.
+ */
+static GstBusSyncReply _sync_bus_handler(GstBus *bus, GstMessage *msg,
+ MafwGstRendererWorker *worker)
+{
+ if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ELEMENT &&
+ gst_structure_has_name(msg->structure, "prepare-xwindow-id"))
+ {
+ g_debug("got prepare-xwindow-id");
+ worker->media.has_visual_content = TRUE;
+ /* The user has to preset the XID, we don't create windows by
+ * ourselves. */
+ if (!worker->xid) {
+ /* We must post an error message to the bus that will
+ * be picked up by _async_bus_handler. Calling the
+ * notification function directly from here (different
+ * thread) is not healthy. */
+ g_warning("No video window set!");
+ _post_error(worker,
+ g_error_new_literal(
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_PLAYBACK,
+ "No video window XID set"));
+ gst_message_unref (msg);
+ return GST_BUS_DROP;
+ } else {
+ g_debug ("Video window to use is: %x",
+ (gint) worker->xid);
+ }
+
+ /* Instruct vsink to use the client-provided window */
+ mafw_gst_renderer_worker_apply_xid(worker);
+
+ /* Handle colorkey and autopaint */
+ mafw_gst_renderer_worker_set_autopaint(
+ worker,
+ worker->autopaint);
+ if (worker->colorkey == -1)
+ g_object_get(worker->vsink,
+ "colorkey", &worker->colorkey, NULL);
+ else
+ mafw_gst_renderer_worker_set_colorkey(
+ worker,
+ worker->colorkey);
+ /* Defer the signal emission to the thread running the
+ * mainloop. */
+ if (worker->colorkey != -1) {
+ gst_bus_post(worker->bus,
+ gst_message_new_application(
+ GST_OBJECT(worker->vsink),
+ gst_structure_empty_new("ckey")));
+ }
+ gst_message_unref (msg);
+ return GST_BUS_DROP;
+ }
+ /* do not unref message when returning PASS */
+ return GST_BUS_PASS;
+}
+
+static void _free_taglist_item(GstMessage *msg, gpointer data)
+{
+ gst_message_unref(msg);
+}
+
+static void _free_taglist(MafwGstRendererWorker *worker)
+{
+ if (worker->tag_list != NULL)
+ {
+ g_ptr_array_foreach(worker->tag_list, (GFunc)_free_taglist_item,
+ NULL);
+ g_ptr_array_free(worker->tag_list, TRUE);
+ worker->tag_list = NULL;
+ }
+}
+
+static gboolean _seconds_duration_equal(gint64 duration1, gint64 duration2)
+{
+ gint64 duration1_seconds, duration2_seconds;
+
+ duration1_seconds = NSECONDS_TO_SECONDS(duration1);
+ duration2_seconds = NSECONDS_TO_SECONDS(duration2);
+
+ return duration1_seconds == duration2_seconds;
+}
+
+static void _check_duration(MafwGstRendererWorker *worker, gint64 value)
+{
+ MafwGstRenderer *renderer = worker->owner;
+ gboolean right_query = TRUE;
+
+ if (value == -1) {
+ GstFormat format = GST_FORMAT_TIME;
+ right_query =
+ gst_element_query_duration(worker->pipeline, &format,
+ &value);
+ }
+
+ if (right_query && value > 0) {
+ gint duration_seconds = NSECONDS_TO_SECONDS(value);
+
+ if (!_seconds_duration_equal(worker->media.length_nanos,
+ value)) {
+ /* Add the duration to the current metadata. */
+ _current_metadata_add(worker, MAFW_METADATA_KEY_DURATION,
+ G_TYPE_INT64,
+ (gint64)duration_seconds);
+ /* Emit the duration. */
+ mafw_renderer_emit_metadata_int64(
+ worker->owner, MAFW_METADATA_KEY_DURATION,
+ (gint64)duration_seconds);
+ }
+
+ /* We compare this duration we just got with the
+ * source one and update it in the source if needed */
+ if (duration_seconds > 0 &&
+ duration_seconds != renderer->media->duration) {
+ mafw_gst_renderer_update_source_duration(
+ renderer,
+ duration_seconds);
+ }
+ }
+
+ worker->media.length_nanos = value;
+ g_debug("media duration: %lld", worker->media.length_nanos);
+}
+
+static void _check_seekability(MafwGstRendererWorker *worker)
+{
+ MafwGstRenderer *renderer = worker->owner;
+ SeekabilityType seekable = SEEKABILITY_NO_SEEKABLE;
+
+ if (worker->media.length_nanos != -1)
+ {
+ g_debug("source seekability %d", renderer->media->seekability);
+
+ if (renderer->media->seekability != SEEKABILITY_NO_SEEKABLE) {
+ g_debug("Quering GStreamer for seekability");
+ GstQuery *seek_query;
+ GstFormat format = GST_FORMAT_TIME;
+ /* Query the seekability of the stream */
+ seek_query = gst_query_new_seeking(format);
+ if (gst_element_query(worker->pipeline, seek_query)) {
+ gboolean renderer_seekable = FALSE;
+ gst_query_parse_seeking(seek_query, NULL,
+ &renderer_seekable,
+ NULL, NULL);
+ g_debug("GStreamer seekability %d",
+ renderer_seekable);
+ seekable = renderer_seekable ?
+ SEEKABILITY_SEEKABLE :
+ SEEKABILITY_NO_SEEKABLE;
+ }
+ gst_query_unref(seek_query);
+ }
+ }
+
+ if (worker->media.seekable != seekable) {
+ gboolean is_seekable = (seekable == SEEKABILITY_SEEKABLE);
+
+ /* Add the seekability to the current metadata. */
+ _current_metadata_add(worker, MAFW_METADATA_KEY_IS_SEEKABLE,
+ G_TYPE_BOOLEAN, is_seekable);
+
+ /* Emit. */
+ mafw_renderer_emit_metadata_boolean(
+ worker->owner, MAFW_METADATA_KEY_IS_SEEKABLE,
+ is_seekable);
+ }
+
+ g_debug("media seekable: %d", seekable);
+ worker->media.seekable = seekable;
+}
+
+static gboolean _query_duration_and_seekability_timeout(gpointer data)
+{
+ MafwGstRendererWorker *worker = data;
+
+ _check_duration(worker, -1);
+ _check_seekability(worker);
+
+ worker->duration_seek_timeout = 0;
+
+ return FALSE;
+}
+
+/*
+ * Called when the pipeline transitions into PAUSED state. It extracts more
+ * information from Gst.
+ */
+static void _finalize_startup(MafwGstRendererWorker *worker)
+{
+ /* Check video caps */
+ if (worker->media.has_visual_content) {
+ GstPad *pad = GST_BASE_SINK_PAD(worker->vsink);
+ GstCaps *caps = GST_PAD_CAPS(pad);
+ if (caps && gst_caps_is_fixed(caps)) {
+ GstStructure *structure;
+ structure = gst_caps_get_structure(caps, 0);
+ if (!_handle_video_info(worker, structure))
+ return;
+ }
+ }
+
+ /* Something might have gone wrong at this point already. */
+ if (worker->is_error) {
+ g_debug("Error occured during preroll");
+ return;
+ }
+
+ /* Streaminfo might reveal the media to be unsupported. Therefore we
+ * need to check the error again. */
+ _parse_stream_info(worker);
+ if (worker->is_error) {
+ g_debug("Error occured. Leaving");
+ return;
+ }
+
+ /* Check duration and seekability */
+ if (worker->duration_seek_timeout != 0) {
+ g_source_remove(worker->duration_seek_timeout);
+ worker->duration_seek_timeout = 0;
+ }
+ _check_duration(worker, -1);
+ _check_seekability(worker);
+}
+
+static void _add_duration_seek_query_timeout(MafwGstRendererWorker *worker)
+{
+ if (worker->duration_seek_timeout != 0) {
+ g_source_remove(worker->duration_seek_timeout);
+ }
+ worker->duration_seek_timeout = g_timeout_add_seconds(
+ MAFW_GST_RENDERER_WORKER_SECONDS_DURATION_AND_SEEKABILITY,
+ _query_duration_and_seekability_timeout,
+ worker);
+}
+
+static void _do_pause_postprocessing(MafwGstRendererWorker *worker)
+{
+ if (worker->notify_pause_handler) {
+ worker->notify_pause_handler(worker, worker->owner);
+ }
+
+#ifdef HAVE_GDKPIXBUF
+ if (worker->media.has_visual_content &&
+ worker->current_frame_on_pause) {
+ GstBuffer *buffer = NULL;
+
+ g_object_get(worker->pipeline, "frame", &buffer, NULL);
+
+ if (buffer != NULL) {
+ _emit_gst_buffer_as_graphic_file(
+ worker, buffer,
+ MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI);
+ }
+ }
+#endif
+
+ _add_ready_timeout(worker);
+}
+
+static void _report_playing_state(MafwGstRendererWorker * worker)
+{
+ if (worker->report_statechanges) {
+ switch (worker->mode) {
+ case WORKER_MODE_SINGLE_PLAY:
+ /* Notify play if we are playing in
+ * single mode */
+ if (worker->notify_play_handler)
+ worker->notify_play_handler(
+ worker,
+ worker->owner);
+ break;
+ case WORKER_MODE_PLAYLIST:
+ case WORKER_MODE_REDUNDANT:
+ /* Only notify play when the "playlist"
+ playback starts, don't notify play for each
+ individual element of the playlist. */
+ if (worker->pl.notify_play_pending) {
+ if (worker->notify_play_handler)
+ worker->notify_play_handler(
+ worker,
+ worker->owner);
+ worker->pl.notify_play_pending = FALSE;
+ }
+ break;
+ default: break;
+ }
+ }
+}
+
+static void _handle_state_changed(GstMessage *msg, MafwGstRendererWorker *worker)
+{
+ GstState newstate, oldstate;
+ GstStateChange statetrans;
+ MafwGstRenderer *renderer = (MafwGstRenderer*)worker->owner;
+
+ gst_message_parse_state_changed(msg, &oldstate, &newstate, NULL);
+ statetrans = GST_STATE_TRANSITION(oldstate, newstate);
+ g_debug ("State changed: %d: %d -> %d", worker->state, oldstate, newstate);
+
+ /* If the state is the same we do nothing, otherwise, we keep
+ * it */
+ if (worker->state == newstate) {
+ return;
+ } else {
+ worker->state = newstate;
+ }
+
+ if (statetrans == GST_STATE_CHANGE_READY_TO_PAUSED &&
+ worker->in_ready) {
+ /* Woken up from READY, resume stream position and playback */
+ g_debug("State changed to pause after ready");
+ if (worker->seek_position > 0) {
+ _check_seekability(worker);
+ if (worker->media.seekable) {
+ g_debug("performing a seek");
+ _do_seek(worker, GST_SEEK_TYPE_SET,
+ worker->seek_position, NULL);
+ } else {
+ g_critical("media is not seekable (and should)");
+ }
+ }
+
+ /* If playing a stream wait for buffering to finish before
+ starting to play */
+ if (!worker->is_stream || worker->is_live) {
+ _do_play(worker);
+ }
+ return;
+ }
+
+ /* While buffering, we have to wait in PAUSED
+ until we reach 100% before doing anything */
+ if (worker->buffering) {
+ if (statetrans == GST_STATE_CHANGE_PAUSED_TO_PLAYING) {
+ /* Mmm... probably the client issued a seek on the
+ * stream and then a play/resume command right away,
+ * so the stream got into PLAYING state while
+ * buffering. When the next buffering signal arrives,
+ * the stream will be PAUSED silently and resumed when
+ * buffering is done (silently too), so let's signal
+ * the state change to PLAYING here. */
+ _report_playing_state(worker);
+ }
+ return;
+ }
+
+ switch (statetrans) {
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ if (worker->prerolling && worker->report_statechanges) {
+ /* PAUSED after pipeline has been
+ * constructed. We check caps, seek and
+ * duration and if staying in pause is needed,
+ * we perform operations for pausing, such as
+ * current frame on pause and signalling state
+ * change and adding the timeout to go to ready */
+ g_debug ("Prerolling done, finalizaing startup");
+ _finalize_startup(worker);
+ _do_play(worker);
+ renderer->play_failed_count = 0;
+
+ if (worker->stay_paused) {
+ _do_pause_postprocessing(worker);
+ }
+ worker->prerolling = FALSE;
+ }
+ break;
+ case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+ /* When pausing we do the stuff, like signalling
+ * state, current frame on pause and timeout to go to
+ * ready */
+ if (worker->report_statechanges) {
+ _do_pause_postprocessing(worker);
+ }
+ break;
+ case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+ /* if seek was called, at this point it is really ended */
+ worker->seek_position = -1;
+ worker->eos = FALSE;
+
+ /* Signal state change if needed */
+ _report_playing_state(worker);
+
+ /* Prevent blanking if we are playing video */
+ if (worker->media.has_visual_content) {
+ blanking_prohibit();
+ }
+ keypadlocking_prohibit();
+ /* Remove the ready timeout if we are playing [again] */
+ _remove_ready_timeout(worker);
+ /* If mode is redundant we are trying to play one of several
+ * candidates, so when we get a successful playback, we notify
+ * the real URI that we are playing */
+ if (worker->mode == WORKER_MODE_REDUNDANT) {
+ mafw_renderer_emit_metadata_string(
+ worker->owner,
+ MAFW_METADATA_KEY_URI,
+ worker->media.location);
+ }
+
+ /* Emit metadata. We wait until we reach the playing
+ state because this speeds up playback start time */
+ _emit_metadatas(worker);
+ /* Query duration and seekability. Useful for vbr
+ * clips or streams. */
+ _add_duration_seek_query_timeout(worker);
+ break;
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ /* If we went to READY, we free the taglist and
+ * deassign the timout it */
+ if (worker->in_ready) {
+ g_debug("changed to GST_STATE_READY");
+ _free_taglist(worker);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void _handle_duration(MafwGstRendererWorker *worker, GstMessage *msg)
+{
+ GstFormat fmt;
+ gint64 duration;
+
+ gst_message_parse_duration(msg, &fmt, &duration);
+
+ if (worker->duration_seek_timeout != 0) {
+ g_source_remove(worker->duration_seek_timeout);
+ worker->duration_seek_timeout = 0;
+ }
+
+ _check_duration(worker,
+ duration != GST_CLOCK_TIME_NONE ? duration : -1);
+ _check_seekability(worker);
+}
+
+#ifdef HAVE_GDKPIXBUF
+static void _emit_renderer_art(MafwGstRendererWorker *worker,
+ const GstTagList *list)
+{
+ GstBuffer *buffer = NULL;
+ const GValue *value = NULL;
+
+ g_return_if_fail(gst_tag_list_get_tag_size(list, GST_TAG_IMAGE) > 0);
+
+ value = gst_tag_list_get_value_index(list, GST_TAG_IMAGE, 0);
+
+ g_return_if_fail((value != NULL) && G_VALUE_HOLDS(value, GST_TYPE_BUFFER));
+
+ buffer = g_value_peek_pointer(value);
+
+ g_return_if_fail((buffer != NULL) && GST_IS_BUFFER(buffer));
+
+ _emit_gst_buffer_as_graphic_file(worker, buffer,
+ MAFW_METADATA_KEY_RENDERER_ART_URI);
+}
+#endif
+
+static GHashTable* _build_tagmap(void)
+{
+ GHashTable *hash_table = NULL;
+
+ hash_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ g_free);
+
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_TITLE),
+ g_strdup(MAFW_METADATA_KEY_TITLE));
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_ARTIST),
+ g_strdup(MAFW_METADATA_KEY_ARTIST));
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_AUDIO_CODEC),
+ g_strdup(MAFW_METADATA_KEY_AUDIO_CODEC));
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_VIDEO_CODEC),
+ g_strdup(MAFW_METADATA_KEY_VIDEO_CODEC));
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_BITRATE),
+ g_strdup(MAFW_METADATA_KEY_BITRATE));
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_LANGUAGE_CODE),
+ g_strdup(MAFW_METADATA_KEY_ENCODING));
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_ALBUM),
+ g_strdup(MAFW_METADATA_KEY_ALBUM));
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_GENRE),
+ g_strdup(MAFW_METADATA_KEY_GENRE));
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_TRACK_NUMBER),
+ g_strdup(MAFW_METADATA_KEY_TRACK));
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_ORGANIZATION),
+ g_strdup(MAFW_METADATA_KEY_ORGANIZATION));
+#ifdef HAVE_GDKPIXBUF
+ g_hash_table_insert(hash_table, g_strdup(GST_TAG_IMAGE),
+ g_strdup(MAFW_METADATA_KEY_RENDERER_ART_URI));
+#endif
+
+ return hash_table;
+}
+
+/*
+ * Emits metadata-changed signals for gst tags.
+ */
+static void _emit_tag(const GstTagList *list, const gchar *tag,
+ MafwGstRendererWorker *worker)
+{
+ /* Mapping between Gst <-> MAFW metadata tags
+ * NOTE: This assumes that GTypes matches between GST and MAFW. */
+ static GHashTable *tagmap = NULL;
+ gint i, count;
+ const gchar *mafwtag;
+ GType type;
+ GValueArray *values;
+
+ if (tagmap == NULL) {
+ tagmap = _build_tagmap();
+ }
+
+ g_debug("tag: '%s' (type: %s)", tag,
+ g_type_name(gst_tag_get_type(tag)));
+ /* Is there a mapping for this tag? */
+ mafwtag = g_hash_table_lookup(tagmap, tag);
+ if (!mafwtag)
+ return;
+
+#ifdef HAVE_GDKPIXBUF
+ if (strcmp (mafwtag, MAFW_METADATA_KEY_RENDERER_ART_URI) == 0) {
+ _emit_renderer_art(worker, list);
+ return;
+ }
+#endif
+
+ /* Build a value array of this tag. We need to make sure that strings
+ * are UTF-8. GstTagList API says that the value is always UTF8, but it
+ * looks like the ID3 demuxer still might sometimes produce non-UTF-8
+ * strings. */
+ count = gst_tag_list_get_tag_size(list, tag);
+ type = gst_tag_get_type(tag);
+ values = g_value_array_new(count);
+ for (i = 0; i < count; ++i) {
+ GValue *v = (GValue *)
+ gst_tag_list_get_value_index(list, tag, i);
+ if (type == G_TYPE_STRING) {
+ gchar *orig, *utf8;
+
+ gst_tag_list_get_string_index(list, tag, i, &orig);
+ if (convert_utf8(orig, &utf8)) {
+ GValue utf8gval = {0};
+
+ g_value_init(&utf8gval, G_TYPE_STRING);
+ g_value_take_string(&utf8gval, utf8);
+ _current_metadata_add(worker, mafwtag, G_TYPE_STRING,
+ utf8);
+ g_value_array_append(values, &utf8gval);
+ g_value_unset(&utf8gval);
+ }
+ g_free(orig);
+ } else if (type == G_TYPE_UINT) {
+ GValue intgval = {0};
+ gint intval;
+
+ g_value_init(&intgval, G_TYPE_INT);
+ g_value_transform(v, &intgval);
+ intval = g_value_get_int(&intgval);
+ _current_metadata_add(worker, mafwtag, G_TYPE_INT,
+ intval);
+ g_value_array_append(values, &intgval);
+ g_value_unset(&intgval);
+ } else {
+ _current_metadata_add(worker, mafwtag, G_TYPE_VALUE,
+ v);
+ g_value_array_append(values, v);
+ }
+ }
+
+ /* Emit the metadata. */
+ g_signal_emit_by_name(worker->owner, "metadata-changed", mafwtag,
+ values);
+
+ g_value_array_free(values);
+}
+
+/**
+ * Collect tag-messages, parse it later, when playing is ongoing
+ */
+static void _handle_tag(MafwGstRendererWorker *worker, GstMessage *msg)
+{
+ /* Do not emit metadata until we get to PLAYING state to speed up
+ playback start */
+ if (worker->tag_list == NULL)
+ worker->tag_list = g_ptr_array_new();
+ g_ptr_array_add(worker->tag_list, gst_message_ref(msg));
+
+ /* Some tags come in playing state, so in this case we have
+ to emit them right away (example: radio stations) */
+ if (worker->state == GST_STATE_PLAYING) {
+ _emit_metadatas(worker);
+ }
+}
+
+/**
+ * Parses the list of tag-messages
+ */
+static void _parse_tagmsg(GstMessage *msg, MafwGstRendererWorker *worker)
+{
+ GstTagList *new_tags;
+
+ gst_message_parse_tag(msg, &new_tags);
+ gst_tag_list_foreach(new_tags, (gpointer)_emit_tag, worker);
+ gst_tag_list_free(new_tags);
+ gst_message_unref(msg);
+}
+
+/**
+ * Parses the collected tag messages, and emits the metadatas
+ */
+static void _emit_metadatas(MafwGstRendererWorker *worker)
+{
+ if (worker->tag_list != NULL)
+ {
+ g_ptr_array_foreach(worker->tag_list, (GFunc)_parse_tagmsg,
+ worker);
+ g_ptr_array_free(worker->tag_list, TRUE);
+ worker->tag_list = NULL;
+ }
+}
+
+static void _reset_volume_and_mute_to_pipeline(MafwGstRendererWorker *worker)
+{
+#ifdef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME
+ g_debug("resetting volume and mute to pipeline");
+
+ if (worker->pipeline != NULL) {
+ g_object_set(
+ G_OBJECT(worker->pipeline), "volume",
+ mafw_gst_renderer_worker_volume_get(worker->wvolume),
+ "mute",
+ mafw_gst_renderer_worker_volume_is_muted(worker->wvolume),
+ NULL);
+ }
+#endif
+}
+
+static void _handle_buffering(MafwGstRendererWorker *worker, GstMessage *msg)
+{
+ gint percent;
+ MafwGstRenderer *renderer = (MafwGstRenderer*)worker->owner;
+
+ gst_message_parse_buffering(msg, &percent);
+ g_debug("buffering: %d", percent);
+
+ /* No state management needed for live pipelines */
+ if (!worker->is_live) {
+ worker->buffering = TRUE;
+ if (percent < 100 && worker->state == GST_STATE_PLAYING) {
+ g_debug("setting pipeline to PAUSED not to wolf the "
+ "buffer down");
+ worker->report_statechanges = FALSE;
+ /* We can't call _pause() here, since it sets
+ * the "report_statechanges" to TRUE. We don't
+ * want that, application doesn't need to know
+ * that internally the state changed to
+ * PAUSED. */
+ if (gst_element_set_state(worker->pipeline,
+ GST_STATE_PAUSED) ==
+ GST_STATE_CHANGE_ASYNC)
+ {
+ /* XXX this blocks at most 2 seconds. */
+ gst_element_get_state(worker->pipeline, NULL,
+ NULL,
+ 2 * GST_SECOND);
+ }
+ }
+
+ if (percent >= 100) {
+ /* On buffering we go to PAUSED, so here we move back to
+ PLAYING */
+ worker->buffering = FALSE;
+ if (worker->state == GST_STATE_PAUSED) {
+ /* If buffering more than once, do this only the
+ first time we are done with buffering */
+ if (worker->prerolling) {
+ g_debug("buffering concluded during "
+ "prerolling");
+ _finalize_startup(worker);
+ _do_play(worker);
+ renderer->play_failed_count = 0;
+ /* Send the paused notification */
+ if (worker->stay_paused &&
+ worker->notify_pause_handler) {
+ worker->notify_pause_handler(
+ worker,
+ worker->owner);
+ }
+ worker->prerolling = FALSE;
+ } else if (worker->in_ready) {
+ /* If we had been woken up from READY
+ and we have finish our buffering,
+ check if we have to play or stay
+ paused and if we have to play,
+ signal the state change. */
+ g_debug("buffering concluded, "
+ "continuing playing");
+ _do_play(worker);
+ } else if (!worker->stay_paused) {
+ /* This means, that we were playing but
+ ran out of buffer, so we silently
+ paused waited for buffering to
+ finish and now we continue silently
+ (silently meaning we do not expose
+ state changes) */
+ g_debug("buffering concluded, setting "
+ "pipeline to PLAYING again");
+ _reset_volume_and_mute_to_pipeline(
+ worker);
+ if (gst_element_set_state(
+ worker->pipeline,
+ GST_STATE_PLAYING) ==
+ GST_STATE_CHANGE_ASYNC)
+ {
+ /* XXX this blocks at most 2 seconds. */
+ gst_element_get_state(
+ worker->pipeline, NULL, NULL,
+ 2 * GST_SECOND);
+ }
+ }
+ } else if (worker->state == GST_STATE_PLAYING) {
+ g_debug("buffering concluded, signalling "
+ "state change");
+ /* In this case we got a PLAY command while
+ buffering, likely because it was issued
+ before we got the first buffering signal.
+ The UI should not do this, but if it does,
+ we have to signal that we have executed
+ the state change, since in
+ _handle_state_changed we do not do anything
+ if we are buffering */
+
+ /* Set the pipeline to playing. This is an async
+ handler, it could be, that the reported state
+ is not the real-current state */
+ if (gst_element_set_state(
+ worker->pipeline,
+ GST_STATE_PLAYING) ==
+ GST_STATE_CHANGE_ASYNC)
+ {
+ /* XXX this blocks at most 2 seconds. */
+ gst_element_get_state(
+ worker->pipeline, NULL, NULL,
+ 2 * GST_SECOND);
+ }
+ if (worker->report_statechanges &&
+ worker->notify_play_handler) {
+ worker->notify_play_handler(
+ worker,
+ worker->owner);
+ }
+ _add_duration_seek_query_timeout(worker);
+ }
+ }
+ }
+
+ /* Send buffer percentage */
+ if (worker->notify_buffer_status_handler)
+ worker->notify_buffer_status_handler(worker, worker->owner,
+ percent);
+}
+
+static void _handle_element_msg(MafwGstRendererWorker *worker, GstMessage *msg)
+{
+ /* Only HelixBin sends "resolution" messages. */
+ if (gst_structure_has_name(msg->structure, "resolution") &&
+ _handle_video_info(worker, msg->structure))
+ {
+ worker->media.has_visual_content = TRUE;
+ }
+}
+
+static void _reset_pl_info(MafwGstRendererWorker *worker)
+{
+ if (worker->pl.items) {
+ g_slist_foreach(worker->pl.items, (GFunc) g_free, NULL);
+ g_slist_free(worker->pl.items);
+ worker->pl.items = NULL;
+ }
+
+ worker->pl.current = 0;
+ worker->pl.notify_play_pending = TRUE;
+}
+
+static GError * _get_specific_missing_plugin_error(GstMessage *msg)
+{
+ const GstStructure *gst_struct;
+ const gchar *type;
+
+ GError *error;
+ gchar *desc;
+
+ desc = gst_missing_plugin_message_get_description(msg);
+
+ gst_struct = gst_message_get_structure(msg);
+ type = gst_structure_get_string(gst_struct, "type");
+
+ if ((type) && ((strcmp(type, MAFW_GST_MISSING_TYPE_DECODER) == 0) ||
+ (strcmp(type, MAFW_GST_MISSING_TYPE_ENCODER) == 0))) {
+
+ /* Missing codec error. */
+ const GValue *val;
+ const GstCaps *caps;
+ GstStructure *caps_struct;
+ const gchar *mime;
+
+ val = gst_structure_get_value(gst_struct, "detail");
+ caps = gst_value_get_caps(val);
+ caps_struct = gst_caps_get_structure(caps, 0);
+ mime = gst_structure_get_name(caps_struct);
+
+ if (g_strrstr(mime, "video")) {
+ error = g_error_new_literal(
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_VIDEO_CODEC_NOT_FOUND,
+ desc);
+ } else if (g_strrstr(mime, "audio")) {
+ error = g_error_new_literal(
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_AUDIO_CODEC_NOT_FOUND,
+ desc);
+ } else {
+ error = g_error_new_literal(
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_CODEC_NOT_FOUND,
+ desc);
+ }
+ } else {
+ /* Unsupported type error. */
+ error = g_error_new(
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_UNSUPPORTED_TYPE,
+ "missing plugin: %s", desc);
+ }
+
+ g_free(desc);
+
+ return error;
+}
+
+/*
+ * Asynchronous message handler. It gets removed from if it returns FALSE.
+ */
+static gboolean _async_bus_handler(GstBus *bus, GstMessage *msg,
+ MafwGstRendererWorker *worker)
+{
+ /* No need to handle message if error has already occured. */
+ if (worker->is_error)
+ return TRUE;
+
+ /* Handle missing-plugin (element) messages separately, relaying more
+ * details. */
+ if (gst_is_missing_plugin_message(msg)) {
+ GError *err = _get_specific_missing_plugin_error(msg);
+ /* FIXME?: for some reason, calling the error handler directly
+ * (_send_error) causes problems. On the other hand, turning
+ * the error into a new GstMessage and letting the next
+ * iteration handle it seems to work. */
+ _post_error(worker, err);
+ return TRUE;
+ }
+
+ switch (GST_MESSAGE_TYPE(msg)) {
+ case GST_MESSAGE_ERROR:
+ if (!worker->is_error) {
+ gchar *debug;
+ GError *err;
+
+ debug = NULL;
+ gst_message_parse_error(msg, &err, &debug);
+ g_debug("gst error: domain = %d, code = %d, "
+ "message = '%s', debug = '%s'",
+ err->domain, err->code, err->message, debug);
+ if (debug)
+ g_free(debug);
+
+ /* If we are in playlist/radio mode, we silently
+ ignore the error and continue with the next
+ item until we end the playlist. If no
+ playable elements we raise the error and
+ after finishing we go to normal mode */
+
+ if (worker->mode == WORKER_MODE_PLAYLIST ||
+ worker->mode == WORKER_MODE_REDUNDANT) {
+ if (worker->pl.current <
+ (g_slist_length(worker->pl.items) - 1)) {
+ /* If the error is "no space left"
+ notify, otherwise try to play the
+ next item */
+ if (err->code ==
+ GST_RESOURCE_ERROR_NO_SPACE_LEFT) {
+ _send_error(worker, err);
+
+ } else {
+ _play_pl_next(worker);
+ }
+ } else {
+ /* Playlist EOS. We cannot try another
+ * URI, so we have to go back to normal
+ * mode and signal the error (done
+ * below) */
+ worker->mode = WORKER_MODE_SINGLE_PLAY;
+ _reset_pl_info(worker);
+ }
+ }
+
+ if (worker->mode == WORKER_MODE_SINGLE_PLAY) {
+ if (err->domain == GST_STREAM_ERROR &&
+ err->code == GST_STREAM_ERROR_WRONG_TYPE)
+ {/* Maybe it is a playlist? */
+ GSList *plitems = _parse_playlist(worker->media.location);
+
+ if (plitems)
+ {/* Yes, it is a plitem */
+ g_error_free(err);
+ mafw_gst_renderer_worker_play(worker, NULL, plitems);
+ break;
+ }
+
+
+ }
+ _send_error(worker, err);
+ }
+ }
+ break;
+ case GST_MESSAGE_EOS:
+ if (!worker->is_error) {
+ worker->eos = TRUE;
+
+ if (worker->mode == WORKER_MODE_PLAYLIST) {
+ if (worker->pl.current <
+ (g_slist_length(worker->pl.items) - 1)) {
+ /* If the playlist EOS is not reached
+ continue playing */
+ _play_pl_next(worker);
+ } else {
+ /* Playlist EOS, go back to normal
+ mode */
+ worker->mode = WORKER_MODE_SINGLE_PLAY;
+ _reset_pl_info(worker);
+ }
+ }
+
+ if (worker->mode == WORKER_MODE_SINGLE_PLAY ||
+ worker->mode == WORKER_MODE_REDUNDANT) {
+ if (worker->notify_eos_handler)
+ worker->notify_eos_handler(
+ worker,
+ worker->owner);
+
+ /* We can remove the message handlers now, we
+ are not interested in bus messages
+ anymore. */
+ if (worker->bus) {
+ gst_bus_set_sync_handler(worker->bus,
+ NULL,
+ NULL);
+ }
+ if (worker->async_bus_id) {
+ g_source_remove(worker->async_bus_id);
+ worker->async_bus_id = 0;
+ }
+
+ if (worker->mode == WORKER_MODE_REDUNDANT) {
+ /* Go to normal mode */
+ worker->mode = WORKER_MODE_SINGLE_PLAY;
+ _reset_pl_info(worker);
+ }
+ }
+ }
+ break;
+ case GST_MESSAGE_TAG:
+ _handle_tag(worker, msg);
+ break;
+ case GST_MESSAGE_BUFFERING:
+ _handle_buffering(worker, msg);
+ break;
+ case GST_MESSAGE_DURATION:
+ _handle_duration(worker, msg);
+ break;
+ case GST_MESSAGE_ELEMENT:
+ _handle_element_msg(worker, msg);
+ break;
+ case GST_MESSAGE_STATE_CHANGED:
+ if ((GstElement *)GST_MESSAGE_SRC(msg) == worker->pipeline)
+ _handle_state_changed(msg, worker);
+ break;
+ case GST_MESSAGE_APPLICATION:
+ if (gst_structure_has_name(gst_message_get_structure(msg),
+ "ckey"))
+ {
+ GValue v = {0};
+ g_value_init(&v, G_TYPE_INT);
+ g_value_set_int(&v, worker->colorkey);
+ mafw_extension_emit_property_changed(
+ MAFW_EXTENSION(worker->owner),
+ MAFW_PROPERTY_RENDERER_COLORKEY,
+ &v);
+ }
+ default: break;
+ }
+ return TRUE;
+}
+
+/* NOTE this function will possibly be called from a different thread than the
+ * glib main thread. */
+static void _stream_info_cb(GstObject *pipeline, GParamSpec *unused,
+ MafwGstRendererWorker *worker)
+{
+ g_debug("stream-info changed");
+ _parse_stream_info(worker);
+}
+
+static void _volume_cb(MafwGstRendererWorkerVolume *wvolume, gdouble volume,
+ gpointer data)
+{
+ MafwGstRendererWorker *worker = data;
+ GValue value = {0, };
+
+ _reset_volume_and_mute_to_pipeline(worker);
+
+ g_value_init(&value, G_TYPE_UINT);
+ g_value_set_uint(&value, (guint) (volume * 100.0));
+ mafw_extension_emit_property_changed(MAFW_EXTENSION(worker->owner),
+ MAFW_PROPERTY_RENDERER_VOLUME,
+ &value);
+}
+
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+
+static void _mute_cb(MafwGstRendererWorkerVolume *wvolume, gboolean mute,
+ gpointer data)
+{
+ MafwGstRendererWorker *worker = data;
+ GValue value = {0, };
+
+ _reset_volume_and_mute_to_pipeline(worker);
+
+ g_value_init(&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean(&value, mute);
+ mafw_extension_emit_property_changed(MAFW_EXTENSION(worker->owner),
+ MAFW_PROPERTY_RENDERER_MUTE,
+ &value);
+}
+
+#endif
+
+/* TODO: I think it's not enought to act on error, we need to handle
+ * DestroyNotify on the given window ourselves, because for example helixbin
+ * does it and silently stops the decoder thread. But it doesn't notify
+ * us... */
+static int xerror(Display *dpy, XErrorEvent *xev)
+{
+ MafwGstRendererWorker *worker;
+
+ if (Global_worker == NULL) {
+ return -1;
+ } else {
+ worker = Global_worker;
+ }
+
+ /* Swallow BadWindow and stop pipeline when the error is about the
+ * currently set xid. */
+ if (worker->xid &&
+ xev->resourceid == worker->xid &&
+ xev->error_code == BadWindow)
+ {
+ g_warning("BadWindow received for current xid (%x).",
+ (gint)xev->resourceid);
+ worker->xid = 0;
+ /* We must post a message to the bus, because this function is
+ * invoked from a different thread (xvimagerenderer's queue). */
+ _post_error(worker, g_error_new_literal(
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_PLAYBACK,
+ "Video window gone"));
+ }
+ return 0;
+}
+
+/*
+ * Resets the media information.
+ */
+static void _reset_media_info(MafwGstRendererWorker *worker)
+{
+ if (worker->media.location) {
+ g_free(worker->media.location);
+ worker->media.location = NULL;
+ }
+ worker->media.length_nanos = -1;
+ worker->media.has_visual_content = FALSE;
+ worker->media.seekable = SEEKABILITY_UNKNOWN;
+ worker->media.video_width = 0;
+ worker->media.video_height = 0;
+ worker->media.fps = 0.0;
+}
+
+static void _set_volume_and_mute(MafwGstRendererWorker *worker, gdouble vol,
+ gboolean mute)
+{
+ g_return_if_fail(worker->wvolume != NULL);
+
+ mafw_gst_renderer_worker_volume_set(worker->wvolume, vol, mute);
+}
+
+static void _set_volume(MafwGstRendererWorker *worker, gdouble new_vol)
+{
+ g_return_if_fail(worker->wvolume != NULL);
+
+ _set_volume_and_mute(
+ worker, new_vol,
+ mafw_gst_renderer_worker_volume_is_muted(worker->wvolume));
+}
+
+static void _set_mute(MafwGstRendererWorker *worker, gboolean mute)
+{
+ g_return_if_fail(worker->wvolume != NULL);
+
+ _set_volume_and_mute(
+ worker, mafw_gst_renderer_worker_volume_get(worker->wvolume),
+ mute);
+}
+
+/*
+ * Start to play the media
+ */
+static void _start_play(MafwGstRendererWorker *worker)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer*) worker->owner;
+ GstStateChangeReturn state_change_info;
+ char *autoload_sub = NULL;
+
+ g_assert(worker->pipeline);
+ g_object_set(G_OBJECT(worker->pipeline),
+ "uri", worker->media.location, NULL);
+
+ if (worker->subtitles.enabled) {
+ autoload_sub = uri_get_subtitle_uri(worker->media.location);
+ if (autoload_sub) {
+ g_debug("SUBURI: %s", autoload_sub);
+ g_object_set(G_OBJECT(worker->pipeline),
+ "suburi", autoload_sub,
+ "subtitle-font-desc", worker->subtitles.font,
+ "subtitle-encoding", worker->subtitles.encoding,
+ NULL);
+
+ gst_element_set_state(worker->pipeline, GST_STATE_READY);
+ g_free(autoload_sub);
+ }
+ } else {
+ g_object_set(G_OBJECT(worker->pipeline), "suburi", NULL, NULL);
+ }
+
+ g_debug("URI: %s", worker->media.location);
+ g_debug("setting pipeline to PAUSED");
+
+ worker->report_statechanges = TRUE;
+ state_change_info = gst_element_set_state(worker->pipeline,
+ GST_STATE_PAUSED);
+ if (state_change_info == GST_STATE_CHANGE_NO_PREROLL) {
+ /* FIXME: for live sources we may have to handle
+ buffering and prerolling differently */
+ g_debug ("Source is live!");
+ worker->is_live = TRUE;
+ }
+ worker->prerolling = TRUE;
+
+ worker->is_stream = uri_is_stream(worker->media.location);
+
+ if (renderer->update_playcount_id > 0) {
+ g_source_remove(renderer->update_playcount_id);
+ renderer->update_playcount_id = 0;
+ }
+
+}
+
+/*
+ * Constructs gst pipeline
+ *
+ * FIXME: Could the same pipeline be used for playing all media instead of
+ * constantly deleting and reconstructing it again?
+ */
+static void _construct_pipeline(MafwGstRendererWorker *worker)
+{
+ g_debug("constructing pipeline");
+ g_assert(worker != NULL);
+
+ /* Return if we have already one */
+ if (worker->pipeline)
+ return;
+
+ _free_taglist(worker);
+
+ g_debug("Creating a new instance of playbin2");
+ worker->pipeline = gst_element_factory_make("playbin2",
+ "playbin");
+ if (worker->pipeline == NULL)
+ {
+ /* Let's try with playbin */
+ g_warning ("playbin2 failed, falling back to playbin");
+ worker->pipeline = gst_element_factory_make("playbin",
+ "playbin");
+
+ if (worker->pipeline) {
+ /* Use nwqueue only for non-rtsp and non-mms(h)
+ streams. */
+ gboolean use_nw;
+ use_nw = worker->media.location &&
+ !g_str_has_prefix(worker->media.location,
+ "rtsp://") &&
+ !g_str_has_prefix(worker->media.location,
+ "mms://") &&
+ !g_str_has_prefix(worker->media.location,
+ "mmsh://");
+
+ g_debug("playbin using network queue: %d", use_nw);
+
+ /* These need a modified version of playbin. */
+ g_object_set(G_OBJECT(worker->pipeline),
+ "nw-queue", use_nw,
+ "no-video-transform", TRUE,
+ NULL);
+ }
+ }
+
+ if (!worker->pipeline) {
+ g_critical("failed to create playback pipeline");
+ g_signal_emit_by_name(MAFW_EXTENSION (worker->owner),
+ "error",
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_UNABLE_TO_PERFORM,
+ "Could not create pipeline");
+ g_assert_not_reached();
+ }
+
+
+ worker->bus = gst_pipeline_get_bus(GST_PIPELINE(worker->pipeline));
+ gst_bus_set_sync_handler(worker->bus,
+ (GstBusSyncHandler)_sync_bus_handler, worker);
+ worker->async_bus_id = gst_bus_add_watch_full(worker->bus,G_PRIORITY_HIGH,
+ (GstBusFunc)_async_bus_handler,
+ worker, NULL);
+
+ /* Listen for changes in stream-info object to find out whether the
+ * media contains video and throw error if application has not provided
+ * video window. */
+ g_signal_connect(worker->pipeline, "notify::stream-info",
+ G_CALLBACK(_stream_info_cb), worker);
+
+#ifndef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME
+
+
+ /* Set audio and video sinks ourselves. We create and configure
+ them only once. */
+ if (!worker->asink) {
+ worker->asink = gst_element_factory_make("pulsesink", NULL);
+ if (!worker->asink) {
+ g_critical("Failed to create pipeline audio sink");
+ g_signal_emit_by_name(MAFW_EXTENSION (worker->owner),
+ "error",
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_UNABLE_TO_PERFORM,
+ "Could not create audio sink");
+ g_assert_not_reached();
+ }
+ gst_object_ref(worker->asink);
+ g_object_set(worker->asink,
+ "buffer-time", (gint64) MAFW_GST_BUFFER_TIME,
+ "latency-time", (gint64) MAFW_GST_LATENCY_TIME,
+ NULL);
+ }
+ g_object_set(worker->pipeline, "audio-sink", worker->asink, NULL);
+#endif
+
+ if (!worker->vsink) {
+ worker->vsink = gst_element_factory_make("xvimagesink", NULL);
+ if (!worker->vsink) {
+ g_critical("Failed to create pipeline video sink");
+ g_signal_emit_by_name(MAFW_EXTENSION (worker->owner),
+ "error",
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_UNABLE_TO_PERFORM,
+ "Could not create video sink");
+ g_assert_not_reached();
+ }
+ gst_object_ref(worker->vsink);
+ g_object_set(G_OBJECT(worker->vsink),
+ "handle-events", TRUE,
+ "force-aspect-ratio", TRUE,
+ NULL);
+ }
+ g_object_set(worker->pipeline,
+ "video-sink", worker->vsink,
+ "flags", 103,
+ NULL);
+
+ if (!worker->tsink) {
+ worker->tsink = gst_element_factory_make("textoverlay", NULL);
+ if (!worker->tsink) {
+ g_critical("Failed to create pipeline text sink");
+ g_signal_emit_by_name(MAFW_EXTENSION (worker->owner),
+ "error",
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_UNABLE_TO_PERFORM,
+ "Could not create text sink");
+ g_assert_not_reached();
+ }
+ gst_object_ref(worker->tsink);
+ }
+ g_object_set(worker->pipeline, "text-sink", worker->tsink, NULL);
+}
+
+/*
+ * @seek_type: GstSeekType
+ * @position: Time in seconds where to seek
+ */
+static void _do_seek(MafwGstRendererWorker *worker, GstSeekType seek_type,
+ gint position, GError **error)
+{
+ gboolean ret;
+ gint64 spos;
+
+ g_assert(worker != NULL);
+
+ if (worker->eos || !worker->media.seekable)
+ goto err;
+
+ /* According to the docs, relative seeking is not so easy:
+ GST_SEEK_TYPE_CUR - change relative to currently configured segment.
+ This can't be used to seek relative to the current playback position -
+ do a position query, calculate the desired position and then do an
+ absolute position seek instead if that's what you want to do. */
+ if (seek_type == GST_SEEK_TYPE_CUR)
+ {
+ gint curpos = mafw_gst_renderer_worker_get_position(worker);
+ position = curpos + position;
+ seek_type = GST_SEEK_TYPE_SET;
+ }
+
+ if (position < 0) {
+ position = 0;
+ }
+
+ worker->seek_position = position;
+ worker->report_statechanges = FALSE;
+ spos = (gint64)position * GST_SECOND;
+ g_debug("seek: type = %d, offset = %lld", seek_type, spos);
+
+ /* If the pipeline has been set to READY by us, then wake it up by
+ setting it to PAUSED (when we get the READY->PAUSED transition
+ we will execute the seek). This way when we seek we disable the
+ READY state (logical, since the player is not idle anymore)
+ allowing the sink to render the destination frame in case of
+ video playback */
+ if (worker->in_ready && worker->state == GST_STATE_READY) {
+ gst_element_set_state(worker->pipeline, GST_STATE_PAUSED);
+ } else {
+ ret = gst_element_seek(worker->pipeline, 1.0, GST_FORMAT_TIME,
+ GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_KEY_UNIT,
+ seek_type, spos,
+ GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
+ if (!ret) {
+ /* Seeking is async, so seek_position should not be
+ invalidated here */
+ goto err;
+ }
+ }
+ return;
+
+err: g_set_error(error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_CANNOT_SET_POSITION,
+ "Seeking to %d failed", position);
+}
+
+/* @vol should be between [0 .. 100], higher values (up to 1000) are allowed,
+ * but probably cause distortion. */
+void mafw_gst_renderer_worker_set_volume(
+ MafwGstRendererWorker *worker, guint volume)
+{
+ _set_volume(worker, CLAMP((gdouble)volume / 100.0, 0.0, 1.0));
+}
+
+guint mafw_gst_renderer_worker_get_volume(
+ MafwGstRendererWorker *worker)
+{
+ return (guint)
+ (mafw_gst_renderer_worker_volume_get(worker->wvolume) * 100);
+}
+
+void mafw_gst_renderer_worker_set_mute(MafwGstRendererWorker *worker,
+ gboolean mute)
+{
+ _set_mute(worker, mute);
+}
+
+gboolean mafw_gst_renderer_worker_get_mute(MafwGstRendererWorker *worker)
+{
+ return mafw_gst_renderer_worker_volume_is_muted(worker->wvolume);
+}
+
+#ifdef HAVE_GDKPIXBUF
+void mafw_gst_renderer_worker_set_current_frame_on_pause(MafwGstRendererWorker *worker,
+ gboolean current_frame_on_pause)
+{
+ worker->current_frame_on_pause = current_frame_on_pause;
+}
+
+gboolean mafw_gst_renderer_worker_get_current_frame_on_pause(MafwGstRendererWorker *worker)
+{
+ return worker->current_frame_on_pause;
+}
+#endif
+
+void mafw_gst_renderer_worker_set_position(MafwGstRendererWorker *worker,
+ GstSeekType seek_type,
+ gint position, GError **error)
+{
+ /* If player is paused and we have a timeout for going to ready
+ * restart it. This is logical, since the user is seeking and
+ * thus, the player is not idle anymore. Also this prevents that
+ * when seeking streams we enter buffering and in the middle of
+ * the buffering process we set the pipeline to ready (which stops
+ * the buffering before it reaches 100%, making the client think
+ * buffering is still going on).
+ */
+ if (worker->ready_timeout) {
+ _remove_ready_timeout(worker);
+ _add_ready_timeout(worker);
+ }
+
+ _do_seek(worker, seek_type, position, error);
+ if (worker->notify_seek_handler)
+ worker->notify_seek_handler(worker, worker->owner);
+}
+
+/*
+ * Gets current position, rounded down into precision of one second. If a seek
+ * is pending, returns the position we are going to seek. Returns -1 on
+ * failure.
+ */
+gint mafw_gst_renderer_worker_get_position(MafwGstRendererWorker *worker)
+{
+ GstFormat format;
+ gint64 time = 0;
+ g_assert(worker != NULL);
+
+ /* If seek is ongoing, return the position where we are seeking. */
+ if (worker->seek_position != -1)
+ {
+ return worker->seek_position;
+ }
+ /* Otherwise query position from pipeline. */
+ format = GST_FORMAT_TIME;
+ if (worker->pipeline &&
+ gst_element_query_position(worker->pipeline, &format, &time))
+ {
+ return (gint)(NSECONDS_TO_SECONDS(time));
+ }
+ return -1;
+}
+
+GHashTable *mafw_gst_renderer_worker_get_current_metadata(
+ MafwGstRendererWorker *worker)
+{
+ return worker->current_metadata;
+}
+
+void mafw_gst_renderer_worker_set_xid(MafwGstRendererWorker *worker, XID xid)
+{
+ /* Check for errors on the target window */
+ XSetErrorHandler(xerror);
+
+ /* Store the target window id */
+ g_debug("Setting xid: %x", (guint)xid);
+ worker->xid = xid;
+
+ /* Check if we should use it right away */
+ mafw_gst_renderer_worker_apply_xid(worker);
+}
+
+XID mafw_gst_renderer_worker_get_xid(MafwGstRendererWorker *worker)
+{
+ return worker->xid;
+}
+
+gboolean mafw_gst_renderer_worker_get_autopaint(
+ MafwGstRendererWorker *worker)
+{
+ return worker->autopaint;
+}
+void mafw_gst_renderer_worker_set_autopaint(
+ MafwGstRendererWorker *worker, gboolean autopaint)
+{
+ worker->autopaint = autopaint;
+ if (worker->vsink)
+ g_object_set(worker->vsink, "autopaint-colorkey",
+ worker->autopaint, NULL);
+}
+
+gint mafw_gst_renderer_worker_get_colorkey(
+ MafwGstRendererWorker *worker)
+{
+ return worker->colorkey;
+}
+
+void mafw_gst_renderer_worker_set_colorkey(
+ MafwGstRendererWorker *worker, gint colorkey)
+{
+ worker->colorkey = colorkey;
+ if (worker->vsink)
+ g_object_set(worker->vsink, "colorkey",
+ worker->colorkey, NULL);
+}
+
+gboolean mafw_gst_renderer_worker_get_seekable(MafwGstRendererWorker *worker)
+{
+ return worker->media.seekable;
+}
+
+static void _play_pl_next(MafwGstRendererWorker *worker) {
+ gchar *next;
+
+ g_assert(worker != NULL);
+ g_return_if_fail(worker->pl.items != NULL);
+
+ next = (gchar *) g_slist_nth_data(worker->pl.items,
+ ++worker->pl.current);
+ mafw_gst_renderer_worker_stop(worker);
+ _reset_media_info(worker);
+
+ worker->media.location = g_strdup(next);
+ _construct_pipeline(worker);
+ _start_play(worker);
+}
+
+static void _do_play(MafwGstRendererWorker *worker)
+{
+ g_assert(worker != NULL);
+
+ if (worker->pipeline == NULL) {
+ g_debug("play without a pipeline!");
+ return;
+ }
+ worker->report_statechanges = TRUE;
+
+ /* If we have to stay paused, we do and add the ready
+ * timeout. Otherwise, we move the pipeline */
+ if (!worker->stay_paused) {
+ /* If pipeline is READY, we move it to PAUSED,
+ * otherwise, to PLAYING */
+ if (worker->state == GST_STATE_READY) {
+ gst_element_set_state(worker->pipeline,
+ GST_STATE_PAUSED);
+ g_debug("setting pipeline to PAUSED");
+ } else {
+ _reset_volume_and_mute_to_pipeline(worker);
+ gst_element_set_state(worker->pipeline,
+ GST_STATE_PLAYING);
+ g_debug("setting pipeline to PLAYING");
+ }
+ }
+ else {
+ g_debug("staying in PAUSED state");
+ _add_ready_timeout(worker);
+ }
+}
+
+void mafw_gst_renderer_worker_play(MafwGstRendererWorker *worker,
+ const gchar *uri, GSList *plitems)
+{
+ g_assert(uri || plitems);
+
+ mafw_gst_renderer_worker_stop(worker);
+ _reset_media_info(worker);
+ _reset_pl_info(worker);
+ /* Check if the item to play is a single item or a playlist. */
+ if (plitems || uri_is_playlist(uri)){
+ gchar *item;
+ /* In case of a playlist we parse it and start playing the first
+ item of the playlist. */
+ if (plitems)
+ {
+ worker->pl.items = plitems;
+ }
+ else
+ {
+ worker->pl.items = _parse_playlist(uri);
+ }
+ if (!worker->pl.items)
+ {
+ _send_error(worker,
+ g_error_new(MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_PLAYLIST_PARSING,
+ "Playlist parsing failed: %s",
+ uri));
+ return;
+ }
+
+ /* Set the playback mode */
+ worker->mode = WORKER_MODE_PLAYLIST;
+ worker->pl.notify_play_pending = TRUE;
+
+ /* Set the item to be played */
+ worker->pl.current = 0;
+ item = (gchar *) g_slist_nth_data(worker->pl.items, 0);
+ worker->media.location = g_strdup(item);
+ } else {
+ /* Single item. Set the playback mode according to that */
+ worker->mode = WORKER_MODE_SINGLE_PLAY;
+
+ /* Set the item to be played */
+ worker->media.location = g_strdup(uri);
+ }
+ _construct_pipeline(worker);
+ _start_play(worker);
+}
+
+void mafw_gst_renderer_worker_play_alternatives(MafwGstRendererWorker *worker,
+ gchar **uris)
+{
+ gint i;
+ gchar *item;
+
+ g_assert(uris && uris[0]);
+
+ mafw_gst_renderer_worker_stop(worker);
+ _reset_media_info(worker);
+ _reset_pl_info(worker);
+
+ /* Add the uris to playlist */
+ i = 0;
+ while (uris[i]) {
+ worker->pl.items =
+ g_slist_append(worker->pl.items, g_strdup(uris[i]));
+ i++;
+ }
+
+ /* Set the playback mode */
+ worker->mode = WORKER_MODE_REDUNDANT;
+ worker->pl.notify_play_pending = TRUE;
+
+ /* Set the item to be played */
+ worker->pl.current = 0;
+ item = (gchar *) g_slist_nth_data(worker->pl.items, 0);
+ worker->media.location = g_strdup(item);
+
+ /* Start playing */
+ _construct_pipeline(worker);
+ _start_play(worker);
+}
+
+/*
+ * Currently, stop destroys the Gst pipeline and resets the worker into
+ * default startup configuration.
+ */
+void mafw_gst_renderer_worker_stop(MafwGstRendererWorker *worker)
+{
+ g_debug("worker stop");
+ g_assert(worker != NULL);
+
+ /* If location is NULL, this is a pre-created pipeline */
+ if (worker->async_bus_id && worker->pipeline && !worker->media.location)
+ return;
+
+ if (worker->pipeline) {
+ g_debug("destroying pipeline");
+ if (worker->async_bus_id) {
+ g_source_remove(worker->async_bus_id);
+ worker->async_bus_id = 0;
+ }
+ gst_bus_set_sync_handler(worker->bus, NULL, NULL);
+ gst_element_set_state(worker->pipeline, GST_STATE_NULL);
+ if (worker->bus) {
+ gst_object_unref(GST_OBJECT_CAST(worker->bus));
+ worker->bus = NULL;
+ }
+ gst_object_unref(GST_OBJECT(worker->pipeline));
+ worker->pipeline = NULL;
+ }
+
+ /* Reset worker */
+ worker->report_statechanges = TRUE;
+ worker->state = GST_STATE_NULL;
+ worker->prerolling = FALSE;
+ worker->is_live = FALSE;
+ worker->buffering = FALSE;
+ worker->is_stream = FALSE;
+ worker->is_error = FALSE;
+ worker->eos = FALSE;
+ worker->seek_position = -1;
+ _remove_ready_timeout(worker);
+ _free_taglist(worker);
+ if (worker->current_metadata) {
+ g_hash_table_destroy(worker->current_metadata);
+ worker->current_metadata = NULL;
+ }
+
+ if (worker->duration_seek_timeout != 0) {
+ g_source_remove(worker->duration_seek_timeout);
+ worker->duration_seek_timeout = 0;
+ }
+
+ /* Reset media iformation */
+ _reset_media_info(worker);
+
+ /* We are not playing, so we can let the screen blank */
+ blanking_allow();
+ keypadlocking_allow();
+
+ /* And now get a fresh pipeline ready */
+ _construct_pipeline(worker);
+}
+
+void mafw_gst_renderer_worker_pause(MafwGstRendererWorker *worker)
+{
+ g_assert(worker != NULL);
+
+ if (worker->buffering && worker->state == GST_STATE_PAUSED &&
+ !worker->prerolling) {
+ /* If we are buffering and get a pause, we have to
+ * signal state change and stay_paused */
+ g_debug("Pausing while buffering, signalling state change");
+ worker->stay_paused = TRUE;
+ if (worker->notify_pause_handler) {
+ worker->notify_pause_handler(
+ worker,
+ worker->owner);
+ }
+ } else {
+ worker->report_statechanges = TRUE;
+
+ if (gst_element_set_state(worker->pipeline, GST_STATE_PAUSED) ==
+ GST_STATE_CHANGE_ASYNC)
+ {
+ /* XXX this blocks at most 2 seconds. */
+ gst_element_get_state(worker->pipeline, NULL, NULL,
+ 2 * GST_SECOND);
+ }
+ blanking_allow();
+ keypadlocking_allow();
+ }
+}
+
+void mafw_gst_renderer_worker_resume(MafwGstRendererWorker *worker)
+{
+ if (worker->mode == WORKER_MODE_PLAYLIST ||
+ worker->mode == WORKER_MODE_REDUNDANT) {
+ /* We must notify play if the "playlist" playback
+ is resumed */
+ worker->pl.notify_play_pending = TRUE;
+ }
+ if (worker->buffering && worker->state == GST_STATE_PAUSED &&
+ !worker->prerolling) {
+ /* If we are buffering we cannot resume, but we know
+ * that the pipeline will be moved to PLAYING as
+ * stay_paused is FALSE, so we just activate the state
+ * change report, this way as soon as buffering is finished
+ * the pipeline will be set to PLAYING and the state
+ * change will be reported */
+ worker->report_statechanges = TRUE;
+ g_debug("Resumed while buffering, activating pipeline state "
+ "changes");
+ /* Notice though that we can receive the Resume before
+ we get any buffering information. In that case
+ we go with the "else" branch and set the pipeline to
+ to PLAYING. However, it is possible that in this case
+ we get the fist buffering signal before the
+ PAUSED -> PLAYING state change. In that case, since we
+ ignore state changes while buffering we never signal
+ the state change to PLAYING. We can only fix this by
+ checking, when we receive a PAUSED -> PLAYING transition
+ if we are buffering, and in that case signal the state
+ change (if we get that transition while buffering
+ is on, it can only mean that the client resumed playback
+ while buffering, and we must notify the state change) */
+ } else {
+ _do_play(worker);
+ }
+}
+
+static void _volume_init_cb(MafwGstRendererWorkerVolume *wvolume,
+ gpointer data)
+{
+ MafwGstRendererWorker *worker = data;
+ gdouble volume;
+ gboolean mute;
+
+ worker->wvolume = wvolume;
+
+ g_debug("volume manager initialized");
+
+ volume = mafw_gst_renderer_worker_volume_get(wvolume);
+ mute = mafw_gst_renderer_worker_volume_is_muted(wvolume);
+ _volume_cb(wvolume, volume, worker);
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+ _mute_cb(wvolume, mute, worker);
+#endif
+}
+
+MafwGstRendererWorker *mafw_gst_renderer_worker_new(gpointer owner)
+{
+ MafwGstRendererWorker *worker;
+ GMainContext *main_context;
+
+ worker = g_new0(MafwGstRendererWorker, 1);
+ worker->mode = WORKER_MODE_SINGLE_PLAY;
+ worker->pl.items = NULL;
+ worker->pl.current = 0;
+ worker->pl.notify_play_pending = TRUE;
+ worker->owner = owner;
+ worker->report_statechanges = TRUE;
+ worker->state = GST_STATE_NULL;
+ worker->seek_position = -1;
+ worker->ready_timeout = 0;
+ worker->in_ready = FALSE;
+ worker->xid = 0;
+ worker->autopaint = TRUE;
+ worker->colorkey = -1;
+ worker->vsink = NULL;
+ worker->asink = NULL;
+ worker->tsink = NULL;
+ worker->tag_list = NULL;
+ worker->current_metadata = NULL;
+ worker->subtitles.enabled = FALSE;
+ worker->subtitles.font = NULL;
+ worker->subtitles.encoding = NULL;
+
+#ifdef HAVE_GDKPIXBUF
+ worker->current_frame_on_pause = FALSE;
+ _init_tmp_files_pool(worker);
+#endif
+ worker->notify_seek_handler = NULL;
+ worker->notify_pause_handler = NULL;
+ worker->notify_play_handler = NULL;
+ worker->notify_buffer_status_handler = NULL;
+ worker->notify_eos_handler = NULL;
+ worker->notify_error_handler = NULL;
+ Global_worker = worker;
+ main_context = g_main_context_default();
+ worker->wvolume = NULL;
+ mafw_gst_renderer_worker_volume_init(main_context,
+ _volume_init_cb, worker,
+ _volume_cb, worker,
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+ _mute_cb,
+#else
+ NULL,
+#endif
+ worker);
+ blanking_init();
+ _construct_pipeline(worker);
+
+ return worker;
+}
+
+void mafw_gst_renderer_worker_exit(MafwGstRendererWorker *worker)
+{
+ blanking_deinit();
+#ifdef HAVE_GDKPIXBUF
+ _destroy_tmp_files_pool(worker);
+#endif
+ mafw_gst_renderer_worker_volume_destroy(worker->wvolume);
+ mafw_gst_renderer_worker_stop(worker);
+}
+/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef MAFW_GST_RENDERER_WORKER_H
+#define MAFW_GST_RENDERER_WORKER_H
+
+#include <X11/Xdefs.h>
+#include <glib-object.h>
+#include <gst/gst.h>
+#include "mafw-gst-renderer-worker-volume.h"
+
+#define MAFW_GST_RENDERER_MAX_TMP_FILES 5
+
+typedef struct _MafwGstRendererWorker MafwGstRendererWorker;
+
+typedef void (*MafwGstRendererWorkerNotifySeekCb)(MafwGstRendererWorker *worker, gpointer owner);
+typedef void (*MafwGstRendererWorkerNotifyPauseCb)(MafwGstRendererWorker *worker, gpointer owner);
+typedef void (*MafwGstRendererWorkerNotifyPlayCb)(MafwGstRendererWorker *worker, gpointer owner);
+typedef void (*MafwGstRendererWorkerNotifyBufferStatusCb)(MafwGstRendererWorker *worker, gpointer owner, gdouble percent);
+typedef void (*MafwGstRendererWorkerNotifyEOSCb)(MafwGstRendererWorker *worker, gpointer owner);
+typedef void (*MafwGstRendererWorkerNotifyErrorCb)(MafwGstRendererWorker *worker,
+ gpointer owner,
+ const GError *error);
+
+typedef enum {
+ WORKER_MODE_SINGLE_PLAY,
+ WORKER_MODE_PLAYLIST,
+ WORKER_MODE_REDUNDANT,
+} PlaybackMode;
+
+typedef enum {
+ SEEKABILITY_UNKNOWN = -1,
+ SEEKABILITY_NO_SEEKABLE,
+ SEEKABILITY_SEEKABLE,
+} SeekabilityType;
+
+/*
+ * media: Information about currently selected media.
+ * location: Current media location
+ * length_nanos: Length of the media, in nanoseconds
+ * has_visual_content: the clip contains some visual content (video)
+ * video_width: If media contains video, this tells the video width
+ * video_height: If media contains video, this tells the video height
+ * seekable: Tells whether the media can be seeked
+ * par_n: Video pixel aspect ratio numerator
+ * par_d: Video pixel aspect ratio denominator
+ * subtitles: Configuration of subtitles.
+ * enabled: Are subtitles enabled
+ * font: Subtitles font description
+ * encoding: Subtitles encoding
+ * owner: Owner of the worker; usually a MafwGstRenderer (FIXME USUALLY?)
+ * pipeline: Playback pipeline
+ * bus: Message bus
+ * state: Current playback pipeline state
+ * is_stream: Is currently playing media a stream
+ * muted: Is the audio muted
+ * eos: Has playback reached EOS already
+ * is_error: Has there been an error situation
+ * buffering: Indicates the buffering state
+ * prerolling: Indicates the prerolling state (NULL -> PAUSED)
+ * report_statechanges: Report state change bus messages
+ * current_volume: Current audio volume [0.0 .. 1.0], see playbin:volume
+ * async_bus_id: ID handle for GstBus
+ * buffer_probe_id: ID of the video renderer buffer probe
+ * seek_position: Indicates the pos where to seek, in seconds
+ * vsink: Video sink element of the pipeline
+ * asink: Audio sink element of the pipeline
+ * tsink: Text sink element of the pipeline
+ * xid: XID for video playback
+ * current_frame_on_pause: whether to emit current frame when pausing
+ */
+struct _MafwGstRendererWorker {
+ struct {
+ gchar *location;
+ gint64 length_nanos;
+ gboolean has_visual_content;
+ gint video_width;
+ gint video_height;
+ gdouble fps;
+ SeekabilityType seekable;
+ gint par_n;
+ gint par_d;
+ } media;
+ struct {
+ gboolean enabled;
+ gchar *font;
+ gchar *encoding;
+ } subtitles;
+ PlaybackMode mode;
+ struct {
+ GSList *items;
+ gint current;
+ gboolean notify_play_pending;
+ } pl;
+ gpointer owner;
+ GstElement *pipeline;
+ GstBus *bus;
+ /* GStreamer state we are considering right now */
+ GstState state;
+ MafwGstRendererWorkerVolume *wvolume;
+ gboolean is_stream;
+ gboolean muted;
+ /* we are handing eos or we did */
+ gboolean eos;
+ /* if we are handling (or handled) and error */
+ gboolean is_error;
+ /* pipeline is buffering */
+ gboolean buffering;
+ /* pipeline is prerolling */
+ gboolean prerolling;
+ /* stream is live and doesn't need prerolling */
+ gboolean is_live;
+ /* if we have to stay in paused though a do_play was
+ * requested. Usually used when pausing in transitioning */
+ gboolean stay_paused;
+ /* this variable should be FALSE while we are hiding state
+ * changed to the UI. This is that GStreamer can perform
+ * state_changes without us requiring it, for example, then
+ * seeking, buffering and so on and we have to hide those
+ * changes */
+ gboolean report_statechanges;
+ guint async_bus_id;
+ gint seek_position;
+ guint ready_timeout;
+ guint duration_seek_timeout;
+ /* After some time PAUSED, we set the pipeline to READY in order to
+ * save resources. This field states if we are in this special
+ * situation.
+ * It is set to TRUE when the state change to READY is requested
+ * and stays like that until we reach again PLAYING state (not PAUSED).
+ * The reason for this is that when resuming streams, we have to
+ * move from READY to PAUSED, then seek to the position where the
+ * stream had been paused, then wait for buffering to finish, and then
+ * play (and notify the state change to PLAYING), and we have to
+ * differentiate this case from the one in which we have entered PAUSED
+ * silently (when we ran out of buffer while playing, because in that
+ * case, when we are done buffering we want to resume playback silently
+ * again.
+ */
+ gboolean in_ready;
+ GstElement *vsink;
+ GstElement *asink;
+ GstElement *tsink;
+ XID xid;
+ gboolean autopaint;
+ gint colorkey;
+ GPtrArray *tag_list;
+ GHashTable *current_metadata;
+
+#ifdef HAVE_GDKPIXBUF
+ gboolean current_frame_on_pause;
+ gchar *tmp_files_pool[MAFW_GST_RENDERER_MAX_TMP_FILES];
+ guint8 tmp_files_pool_index;
+#endif
+
+ /* Handlers for notifications */
+ MafwGstRendererWorkerNotifySeekCb notify_seek_handler;
+ MafwGstRendererWorkerNotifyPauseCb notify_pause_handler;
+ MafwGstRendererWorkerNotifyPlayCb notify_play_handler;
+ MafwGstRendererWorkerNotifyBufferStatusCb notify_buffer_status_handler;
+ MafwGstRendererWorkerNotifyEOSCb notify_eos_handler;
+ MafwGstRendererWorkerNotifyErrorCb notify_error_handler;
+};
+
+G_BEGIN_DECLS
+
+MafwGstRendererWorker *mafw_gst_renderer_worker_new(gpointer owner);
+void mafw_gst_renderer_worker_exit(MafwGstRendererWorker *worker);
+
+void mafw_gst_renderer_worker_set_volume(MafwGstRendererWorker *worker,
+ guint vol);
+guint mafw_gst_renderer_worker_get_volume(MafwGstRendererWorker *worker);
+void mafw_gst_renderer_worker_set_mute(MafwGstRendererWorker *worker,
+ gboolean mute);
+gboolean mafw_gst_renderer_worker_get_mute(MafwGstRendererWorker *worker);
+#ifdef HAVE_GDKPIXBUF
+void mafw_gst_renderer_worker_set_current_frame_on_pause(MafwGstRendererWorker *worker,
+ gboolean current_frame_on_pause);
+gboolean mafw_gst_renderer_worker_get_current_frame_on_pause(MafwGstRendererWorker *worker);
+#endif
+void mafw_gst_renderer_worker_set_position(MafwGstRendererWorker *worker,
+ GstSeekType seek_type,
+ gint position,
+ GError **error);
+gint mafw_gst_renderer_worker_get_position(MafwGstRendererWorker *worker);
+void mafw_gst_renderer_worker_set_xid(MafwGstRendererWorker *worker, XID xid);
+XID mafw_gst_renderer_worker_get_xid(MafwGstRendererWorker *worker);
+gboolean mafw_gst_renderer_worker_get_autopaint(MafwGstRendererWorker *worker);
+void mafw_gst_renderer_worker_set_autopaint(MafwGstRendererWorker *worker, gboolean autopaint);
+gint mafw_gst_renderer_worker_get_colorkey(MafwGstRendererWorker *worker);
+void mafw_gst_renderer_worker_set_colorkey(MafwGstRendererWorker *worker, gint autopaint);
+gboolean mafw_gst_renderer_worker_get_seekable(MafwGstRendererWorker *worker);
+GHashTable *mafw_gst_renderer_worker_get_current_metadata(MafwGstRendererWorker *worker);
+void mafw_gst_renderer_worker_play(MafwGstRendererWorker *worker, const gchar *uri, GSList *plitems);
+void mafw_gst_renderer_worker_play_alternatives(MafwGstRendererWorker *worker, gchar **uris);
+void mafw_gst_renderer_worker_stop(MafwGstRendererWorker *worker);
+void mafw_gst_renderer_worker_pause(MafwGstRendererWorker *worker);
+void mafw_gst_renderer_worker_resume(MafwGstRendererWorker *worker);
+
+G_END_DECLS
+#endif
+/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dbus/dbus.h>
+#include <libgnomevfs/gnome-vfs.h>
+
+#include <libmafw/mafw.h>
+#include "mafw-gst-renderer.h"
+#include "mafw-gst-renderer-utils.h"
+#include "mafw-gst-renderer-worker.h"
+
+#include "mafw-gst-renderer-state-playing.h"
+#include "mafw-gst-renderer-state-stopped.h"
+#include "mafw-gst-renderer-state-paused.h"
+#include "mafw-gst-renderer-state-transitioning.h"
+
+#include "blanking.h"
+
+#ifdef HAVE_CONIC
+#include <conicconnectionevent.h>
+#endif
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer"
+
+#define is_current_uri_stream(self) \
+ (((self)->media != NULL) && ((self)->media->uri != NULL) && \
+ uri_is_stream((self)->media->uri))
+
+#define GCONF_OSSO_AF "/system/osso/af"
+#define GCONF_BATTERY_COVER_OPEN "/system/osso/af/mmc-cover-open"
+#define GCONF_MAFW_GST_SUBTITLES_RENDERER "/system/mafw/mafw-gst-subtitles-renderer"
+#define HAL_VIDEOOUT_UDI "/org/freedesktop/Hal/devices" \
+ "/platform_soc_audio_logicaldev_input"
+
+/*----------------------------------------------------------------------------
+ Static variable definitions
+ ----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Plugin initialization
+ ----------------------------------------------------------------------------*/
+
+static gboolean mafw_gst_renderer_initialize(MafwRegistry *registry,
+ GError **error);
+static void mafw_gst_renderer_deinitialize(GError **error);
+
+/*----------------------------------------------------------------------------
+ GObject initialization
+ ----------------------------------------------------------------------------*/
+
+static void mafw_gst_renderer_dispose(GObject *object);
+static void mafw_gst_renderer_finalize(GObject *object);
+
+/*----------------------------------------------------------------------------
+ Hal callbacks
+ ----------------------------------------------------------------------------*/
+static void _property_modified(LibHalContext *ctx, const char *udi,
+ const char *key, dbus_bool_t is_removed,
+ dbus_bool_t is_added);
+static gboolean _tv_out_is_connected(LibHalContext *ctx, const char *udi);
+
+/*----------------------------------------------------------------------------
+ GConf notifications
+ ----------------------------------------------------------------------------*/
+
+static void _battery_cover_open_cb(GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ MafwGstRenderer *renderer);
+
+static void _autoload_subtitles_changed_cb(GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ MafwGstRenderer *renderer);
+
+static void _subtitle_font_changed_cb(GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ MafwGstRenderer *renderer);
+
+/*----------------------------------------------------------------------------
+ Gnome VFS notifications
+ ----------------------------------------------------------------------------*/
+
+static void _volume_pre_unmount_cb(GnomeVFSVolumeMonitor *monitor,
+ GnomeVFSVolume *volume,
+ MafwGstRenderer *renderer);
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+static void _signal_state_changed(MafwGstRenderer * self);
+static void _signal_media_changed(MafwGstRenderer * self);
+static void _signal_playlist_changed(MafwGstRenderer * self);
+static void _signal_transport_actions_property_changed(MafwGstRenderer * self);
+
+/*----------------------------------------------------------------------------
+ Properties
+ ----------------------------------------------------------------------------*/
+
+static void _set_error_policy(MafwGstRenderer *renderer, MafwRendererErrorPolicy policy);
+static MafwRendererErrorPolicy _get_error_policy(MafwGstRenderer *renderer);
+
+static void mafw_gst_renderer_set_property(MafwExtension *self, const gchar *key,
+ const GValue *value);
+static void mafw_gst_renderer_get_property(MafwExtension *self, const gchar *key,
+ MafwExtensionPropertyCallback callback,
+ gpointer user_data);
+
+/*----------------------------------------------------------------------------
+ Metadata
+ ----------------------------------------------------------------------------*/
+
+static void _notify_metadata(MafwSource *cb_source,
+ const gchar *cb_object_id,
+ GHashTable *cb_metadata,
+ gpointer cb_user_data,
+ const GError *cb_error);
+
+/*----------------------------------------------------------------------------
+ Notification operations
+ ----------------------------------------------------------------------------*/
+
+static void _notify_play(MafwGstRendererWorker *worker, gpointer owner);
+static void _notify_pause(MafwGstRendererWorker *worker, gpointer owner);
+static void _notify_seek(MafwGstRendererWorker *worker, gpointer owner);
+static void _notify_buffer_status(MafwGstRendererWorker *worker, gpointer owner,
+ gdouble percent);
+static void _notify_eos(MafwGstRendererWorker *worker, gpointer owner);
+static void _error_handler(MafwGstRendererWorker *worker, gpointer owner,
+ const GError *error);
+
+#ifdef HAVE_CONIC
+/*----------------------------------------------------------------------------
+ Connection
+ ----------------------------------------------------------------------------*/
+
+static void _connection_init(MafwGstRenderer *renderer);
+#endif
+
+/*----------------------------------------------------------------------------
+ Plugin initialization
+ ----------------------------------------------------------------------------*/
+
+/*
+ * Registers the plugin descriptor making this plugin available to the
+ * framework and applications
+ */
+G_MODULE_EXPORT MafwPluginDescriptor mafw_gst_renderer_plugin_description = {
+ { .name = MAFW_GST_RENDERER_PLUGIN_NAME },
+ .initialize = mafw_gst_renderer_initialize,
+ .deinitialize = mafw_gst_renderer_deinitialize,
+};
+
+static gboolean mafw_gst_renderer_initialize(MafwRegistry *registry,
+ GError **error)
+{
+ MafwGstRenderer *self;
+
+ g_assert(registry != NULL);
+ self = MAFW_GST_RENDERER(mafw_gst_renderer_new(registry));
+ mafw_registry_add_extension(registry, MAFW_EXTENSION(self));
+
+ return TRUE;
+}
+
+static void mafw_gst_renderer_deinitialize(GError **error)
+{
+}
+
+/*----------------------------------------------------------------------------
+ GObject initialization
+ ----------------------------------------------------------------------------*/
+
+G_DEFINE_TYPE(MafwGstRenderer, mafw_gst_renderer, MAFW_TYPE_RENDERER);
+
+static void mafw_gst_renderer_class_init(MafwGstRendererClass *klass)
+{
+ GObjectClass *gclass = NULL;
+ MafwRendererClass *renderer_class = NULL;
+ const gchar *preloaded_plugins[] = {"playback", "uridecodebin",
+ "coreelements", "typefindfunctions", "dsp",
+ "pulseaudio", "xvimagesink", NULL};
+ gint i = 0;
+ GObject *plugin;
+
+ gclass = G_OBJECT_CLASS(klass);
+ g_return_if_fail(gclass != NULL);
+
+ renderer_class = MAFW_RENDERER_CLASS(klass);
+ g_return_if_fail(renderer_class != NULL);
+
+ /* GObject */
+
+ gclass->dispose = mafw_gst_renderer_dispose;
+ gclass->finalize = mafw_gst_renderer_finalize;
+
+ /* Playback */
+
+ renderer_class->play = mafw_gst_renderer_play;
+ renderer_class->play_object = mafw_gst_renderer_play_object;
+ renderer_class->stop = mafw_gst_renderer_stop;
+ renderer_class->pause = mafw_gst_renderer_pause;
+ renderer_class->resume = mafw_gst_renderer_resume;
+ renderer_class->get_status = mafw_gst_renderer_get_status;
+
+ /* Playlist operations */
+
+ renderer_class->assign_playlist = mafw_gst_renderer_assign_playlist;
+ renderer_class->next = mafw_gst_renderer_next;
+ renderer_class->previous = mafw_gst_renderer_previous;
+ renderer_class->goto_index = mafw_gst_renderer_goto_index;
+
+ /* Playback position */
+
+ renderer_class->set_position = mafw_gst_renderer_set_position;
+ renderer_class->get_position = mafw_gst_renderer_get_position;
+
+ /* Metadata */
+
+ renderer_class->get_current_metadata =
+ mafw_gst_renderer_get_current_metadata;
+
+ /* Properties */
+
+ MAFW_EXTENSION_CLASS(klass)->get_extension_property =
+ (gpointer) mafw_gst_renderer_get_property;
+ MAFW_EXTENSION_CLASS(klass)->set_extension_property =
+ (gpointer) mafw_gst_renderer_set_property;
+
+ gst_init(NULL, NULL);
+ gst_pb_utils_init();
+
+ /* Pre-load some common plugins */
+ while (preloaded_plugins[i])
+ {
+ plugin = G_OBJECT(gst_plugin_load_by_name(preloaded_plugins[i]));
+ if (plugin)
+ g_object_unref(plugin);
+ else
+ g_debug("Can not load plugin: %s", preloaded_plugins[i]);
+ i++;
+ }
+}
+
+static void mafw_gst_renderer_init(MafwGstRenderer *self)
+{
+ MafwGstRenderer *renderer = NULL;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ renderer = MAFW_GST_RENDERER(self);
+ g_return_if_fail(renderer != NULL);
+
+ mafw_extension_add_property(MAFW_EXTENSION(self), "volume", G_TYPE_UINT);
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+ mafw_extension_add_property(MAFW_EXTENSION(self), "mute", G_TYPE_BOOLEAN);
+#endif
+ mafw_extension_add_property(MAFW_EXTENSION(self), "xid", G_TYPE_UINT);
+ mafw_extension_add_property(MAFW_EXTENSION(self), "error-policy", G_TYPE_UINT);
+ MAFW_EXTENSION_SUPPORTS_AUTOPAINT(self);
+ MAFW_EXTENSION_SUPPORTS_COLORKEY(self);
+#ifdef HAVE_GDKPIXBUF
+ mafw_extension_add_property(MAFW_EXTENSION(self),
+ "current-frame-on-pause",
+ G_TYPE_BOOLEAN);
+#endif
+ mafw_extension_add_property(MAFW_EXTENSION(self),
+ MAFW_PROPERTY_GST_RENDERER_TV_CONNECTED,
+ G_TYPE_BOOLEAN);
+ MAFW_EXTENSION_SUPPORTS_TRANSPORT_ACTIONS(self);
+ renderer->media = g_new0(MafwGstRendererMedia, 1);
+ renderer->media->seekability = SEEKABILITY_UNKNOWN;
+ renderer->current_state = Stopped;
+
+ renderer->playlist = NULL;
+ renderer->iterator = NULL;
+ renderer->seeking_to = -1;
+ renderer->update_playcount_id = 0;
+
+ self->worker = mafw_gst_renderer_worker_new(self);
+
+ /* Set notification handlers for worker */
+ renderer->worker->notify_play_handler = _notify_play;
+ renderer->worker->notify_pause_handler = _notify_pause;
+ renderer->worker->notify_seek_handler = _notify_seek;
+ renderer->worker->notify_error_handler = _error_handler;
+ renderer->worker->notify_eos_handler = _notify_eos;
+ renderer->worker->notify_buffer_status_handler = _notify_buffer_status;
+
+ renderer->states = g_new0 (MafwGstRendererState*, _LastMafwPlayState);
+ renderer->states[Stopped] =
+ MAFW_GST_RENDERER_STATE(mafw_gst_renderer_state_stopped_new(self));
+ renderer->states[Transitioning] =
+ MAFW_GST_RENDERER_STATE(
+ mafw_gst_renderer_state_transitioning_new(self));
+ renderer->states[Playing] =
+ MAFW_GST_RENDERER_STATE(mafw_gst_renderer_state_playing_new(self));
+ renderer->states[Paused] =
+ MAFW_GST_RENDERER_STATE(mafw_gst_renderer_state_paused_new(self));
+
+ renderer->current_state = Stopped;
+ renderer->resume_playlist = FALSE;
+ renderer->playback_mode = MAFW_GST_RENDERER_MODE_PLAYLIST;
+
+#ifdef HAVE_CONIC
+ renderer->connected = FALSE;
+ renderer->connection = NULL;
+
+ _connection_init(renderer);
+#endif
+ renderer->gconf_client = gconf_client_get_default();
+ gconf_client_add_dir(renderer->gconf_client, GCONF_OSSO_AF,
+ GCONF_CLIENT_PRELOAD_ONELEVEL, &error);
+ if (error) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ error = NULL;
+ }
+
+ gconf_client_notify_add(renderer->gconf_client,
+ GCONF_BATTERY_COVER_OPEN,
+ (GConfClientNotifyFunc) _battery_cover_open_cb,
+ renderer,
+ NULL, &error);
+
+ if (error) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ }
+
+ gconf_client_add_dir(renderer->gconf_client,
+ GCONF_MAFW_GST_SUBTITLES_RENDERER,
+ GCONF_CLIENT_PRELOAD_ONELEVEL,
+ &error);
+ if (error) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ error = NULL;
+ }
+
+ gconf_client_notify_add(renderer->gconf_client,
+ GCONF_MAFW_GST_SUBTITLES_RENDERER "/autoload_subtitles",
+ (GConfClientNotifyFunc) _autoload_subtitles_changed_cb,
+ renderer,
+ NULL, &error);
+ if (error) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ }
+
+ gconf_client_notify_add(renderer->gconf_client,
+ GCONF_MAFW_GST_SUBTITLES_RENDERER "/subtitle_encoding",
+ (GConfClientNotifyFunc) _subtitle_font_changed_cb,
+ renderer,
+ NULL, &error);
+ if (error) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ }
+
+ gconf_client_notify_add(renderer->gconf_client,
+ GCONF_MAFW_GST_SUBTITLES_RENDERER "/subtitle_font",
+ (GConfClientNotifyFunc) _subtitle_font_changed_cb,
+ renderer,
+ NULL, &error);
+ if (error) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ }
+
+ if (self->worker->pipeline) {
+ gconf_client_notify(renderer->gconf_client,
+ GCONF_MAFW_GST_SUBTITLES_RENDERER "/autoload_subtitles");
+
+ gconf_client_notify(renderer->gconf_client,
+ GCONF_MAFW_GST_SUBTITLES_RENDERER "/subtitle_encoding");
+
+ gconf_client_notify(renderer->gconf_client,
+ GCONF_MAFW_GST_SUBTITLES_RENDERER "/subtitle_font");
+ }
+
+ if (gnome_vfs_init()) {
+ GnomeVFSVolumeMonitor *monitor = gnome_vfs_get_volume_monitor();
+ g_signal_connect(monitor, "volume-pre-unmount",
+ G_CALLBACK(_volume_pre_unmount_cb), renderer);
+ } else {
+ g_warning("Failed to initialize gnome-vfs");
+ }
+}
+
+static void mafw_gst_renderer_dispose(GObject *object)
+{
+ MafwGstRenderer *renderer;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(object));
+
+ renderer = MAFW_GST_RENDERER(object);
+
+ if (renderer->worker != NULL) {
+ mafw_gst_renderer_worker_exit(renderer->worker);
+ renderer->seek_pending = FALSE;
+ g_free(renderer->worker);
+ renderer->worker = NULL;
+ }
+
+ if (renderer->registry != NULL) {
+ g_object_unref(renderer->registry);
+ renderer->registry = NULL;
+ }
+
+ if (renderer->states != NULL) {
+ guint i = 0;
+
+ for (i = 0; i < _LastMafwPlayState; i++) {
+ if (renderer->states[i] != NULL)
+ g_object_unref(renderer->states[i]);
+ }
+ g_free(renderer->states);
+ renderer->states = NULL;
+ }
+
+ if (renderer->hal_ctx != NULL) {
+ libhal_device_remove_property_watch(renderer->hal_ctx,
+ HAL_VIDEOOUT_UDI,
+ NULL);
+ libhal_ctx_shutdown(renderer->hal_ctx, NULL);
+ libhal_ctx_free(renderer->hal_ctx);
+ }
+
+#ifdef HAVE_CONIC
+ if (renderer->connection != NULL) {
+ g_object_unref(renderer->connection);
+ renderer->connection = NULL;
+ }
+#endif
+
+ if (renderer->gconf_client != NULL) {
+ g_object_unref(renderer->gconf_client);
+ renderer->gconf_client = NULL;
+ }
+
+ G_OBJECT_CLASS(mafw_gst_renderer_parent_class)->dispose(object);
+}
+
+static void mafw_gst_renderer_finalize(GObject *object)
+{
+ MafwGstRenderer *self = (MafwGstRenderer*) object;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ mafw_gst_renderer_clear_media(self);
+
+ if (self->media)
+ {
+ g_free(self->media);
+ self->media = NULL;
+ }
+
+ G_OBJECT_CLASS(mafw_gst_renderer_parent_class)->finalize(object);
+}
+
+/**
+ * mafw_gst_renderer_new:
+ * @registry: The registry that owns this renderer.
+ *
+ * Creates a new MafwGstRenderer object
+ */
+GObject *mafw_gst_renderer_new(MafwRegistry* registry)
+{
+ GObject* object;
+ LibHalContext *ctx;
+ DBusConnection *conn;
+ DBusError err;
+ char **jackets;
+ char **jack;
+ gint num_jacks;
+
+ object = g_object_new(MAFW_TYPE_GST_RENDERER,
+ "uuid", MAFW_GST_RENDERER_UUID,
+ "name", MAFW_GST_RENDERER_NAME,
+ "plugin", MAFW_GST_RENDERER_PLUGIN_NAME,
+ NULL);
+ g_assert(object != NULL);
+ MAFW_GST_RENDERER(object)->registry = g_object_ref(registry);
+
+ /* Set default error policy */
+ MAFW_GST_RENDERER(object)->error_policy =
+ MAFW_RENDERER_ERROR_POLICY_CONTINUE;
+
+ MAFW_GST_RENDERER(object)->tv_connected = FALSE;
+
+ /* Setup hal connection for reacting usb cable connected event */
+ dbus_error_init(&err);
+ conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+
+ if (dbus_error_is_set(&err)) {
+ g_warning("Couldn't setup HAL connection: %s", err.message);
+ dbus_error_free(&err);
+
+ goto err1;
+ }
+ ctx = libhal_ctx_new();
+ libhal_ctx_set_dbus_connection(ctx, conn);
+ libhal_ctx_set_user_data(ctx, object);
+
+ if (libhal_ctx_init(ctx, &err) == FALSE) {
+ if (dbus_error_is_set(&err)) {
+ g_warning("Could not initialize hal: %s", err.message);
+ dbus_error_free(&err);
+ } else {
+ g_warning("Could not initialize hal");
+ }
+ goto err2;
+ }
+
+ libhal_device_add_property_watch(ctx, HAL_VIDEOOUT_UDI, &err);
+
+ if (dbus_error_is_set(&err)) {
+ g_warning("Could not start watching usb device: %s",
+ err.message);
+ dbus_error_free(&err);
+
+ goto err3;
+ }
+ libhal_ctx_set_device_property_modified(ctx, _property_modified);
+
+ /* Initializes blanking policy */
+ jackets = libhal_find_device_by_capability(ctx,
+ "input.jack.video-out",
+ &num_jacks, NULL);
+ if (jackets != NULL) {
+ jack = jackets;
+ while (*jack) {
+ if (_tv_out_is_connected(ctx, *jack)) {
+ MAFW_GST_RENDERER(object)->tv_connected = TRUE;
+ break;
+ }
+ jack++;
+ }
+
+ blanking_control(*jack == NULL);
+ libhal_free_string_array(jackets);
+ }
+
+ MAFW_GST_RENDERER(object)->hal_ctx = ctx;
+
+ return object;
+err3:
+ libhal_ctx_shutdown(ctx, NULL);
+err2:
+ libhal_ctx_free(ctx);
+err1:
+ return object;
+}
+
+/**
+ * mafw_gst_renderer_error_quark:
+ *
+ * Fetches the quark representing the domain of the errors in the
+ * gst renderer
+ *
+ * Return value: a quark identifying the error domain of the
+ * #MafwGstRenderer objects.
+ *
+ **/
+GQuark mafw_gst_renderer_error_quark(void)
+{
+ return g_quark_from_static_string("mafw-gst-renderer-error-quark");
+}
+
+void mafw_gst_renderer_set_playback_mode(MafwGstRenderer *self,
+ MafwGstRendererPlaybackMode mode)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+ self->playback_mode = mode;
+}
+
+MafwGstRendererPlaybackMode mafw_gst_renderer_get_playback_mode(
+ MafwGstRenderer *self)
+{
+ g_return_val_if_fail(MAFW_IS_GST_RENDERER(self),
+ MAFW_GST_RENDERER_MODE_STANDALONE);
+ return self->playback_mode;
+}
+
+/*----------------------------------------------------------------------------
+ Set Media
+ ----------------------------------------------------------------------------*/
+
+static MafwSource* _get_source(MafwGstRenderer *renderer,
+ const gchar *object_id)
+{
+ MafwSource* source;
+ gchar* sourceid = NULL;
+
+ g_assert(object_id != NULL);
+
+ /* Attempt to find a source that provided the object ID */
+ mafw_source_split_objectid(object_id, &sourceid, NULL);
+ source = MAFW_SOURCE(mafw_registry_get_extension_by_uuid(
+ renderer->registry, sourceid));
+ g_free(sourceid);
+
+ return source;
+}
+
+void mafw_gst_renderer_get_metadata(MafwGstRenderer* self,
+ const gchar* objectid,
+ GError **error)
+{
+ MafwSource* source;
+
+ g_assert(self != NULL);
+
+ /*
+ * Any error here is an error when trying to Play, so
+ * it must be handled by error policy.
+ * Problem: if we get an error here and we are not in
+ * Transitioning yet (maybe we are still in Stopped state)
+ * then the policy may move to next and stay Stopped (instead of
+ * trying to play), so errors need to be handled by the policy
+ * in an idle callback, so that any error that may happen here
+ * is not processed until we have moved to Transitioning state
+ */
+
+ source = _get_source(self, objectid);
+ if (source != NULL)
+ {
+ /* List of metadata keys that we are interested in when going to
+ Transitioning state */
+ static const gchar * const keys[] =
+ { MAFW_METADATA_KEY_URI,
+ MAFW_METADATA_KEY_IS_SEEKABLE,
+ MAFW_METADATA_KEY_DURATION,
+ NULL };
+
+ /* Source found, get metadata */
+ mafw_source_get_metadata(source, objectid,
+ keys,
+ _notify_metadata,
+ self);
+
+ }
+ else
+ {
+ /* This is a playback error: execute error policy */
+ MafwGstRendererErrorClosure *error_closure;
+ error_closure = g_new0(MafwGstRendererErrorClosure, 1);
+ error_closure->renderer = self;
+ g_set_error (&(error_closure->error),
+ MAFW_EXTENSION_ERROR,
+ MAFW_EXTENSION_ERROR_EXTENSION_NOT_AVAILABLE,
+ "Unable to find source for current object ID");
+ g_idle_add(mafw_gst_renderer_manage_error_idle, error_closure);
+ }
+}
+
+void mafw_gst_renderer_set_object(MafwGstRenderer *self, const gchar *object_id)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer *) self;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+ g_return_if_fail(object_id != NULL);
+
+ /* This is intended to be called only when using play_object(),
+ * as for playlists we use set_media_playlist()
+ */
+
+ /* Stop any ongoing playback */
+ mafw_gst_renderer_clear_media(renderer);
+
+ /* Set new object */
+ renderer->media->object_id = g_strdup(object_id);
+
+ /* Signal media changed */
+ _signal_media_changed(renderer);
+}
+
+
+/**
+ * mafw_gst_renderer_clear_media:
+ *
+ * @renderer A #MafwGstRenderer whose media to clear
+ *
+ * Clears & frees the renderer's current media details
+ **/
+void mafw_gst_renderer_clear_media(MafwGstRenderer *self)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+ g_return_if_fail(self->media != NULL);
+
+ g_free(self->media->object_id);
+ self->media->object_id = NULL;
+
+ g_free(self->media->uri);
+ self->media->uri = NULL;
+
+ g_free(self->media->title);
+ self->media->title = NULL;
+
+ g_free(self->media->artist);
+ self->media->artist = NULL;
+
+ g_free(self->media->album);
+ self->media->album = NULL;
+
+ self->media->duration = 0;
+ self->media->position = 0;
+}
+
+
+/**
+ * mafw_gst_renderer_set_media_playlist:
+ *
+ * @self A #MafwGstRenderer, whose media to set
+ *
+ * Set current media from the renderer's playlist, using the current playlist index.
+ **/
+void mafw_gst_renderer_set_media_playlist(MafwGstRenderer* self)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ /* Get rid of old media details */
+ mafw_gst_renderer_clear_media(self);
+
+ if (self->playlist != NULL &&
+ mafw_playlist_iterator_get_size(self->iterator, NULL) > 0) {
+ /* Get the current item from playlist */
+ self->media->object_id =
+ g_strdup(mafw_playlist_iterator_get_current_objectid(self->iterator));
+ } else {
+ self->media->object_id = NULL;
+ }
+
+ _signal_media_changed(self);
+}
+
+#ifdef HAVE_CONIC
+/*----------------------------------------------------------------------------
+ Connection
+ ----------------------------------------------------------------------------*/
+
+static void
+_con_ic_status_handler(ConIcConnection *conn, ConIcConnectionEvent *event,
+ gpointer data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer *) data;
+
+ g_assert(MAFW_IS_GST_RENDERER(renderer));
+
+ renderer->connected =
+ con_ic_connection_event_get_status(event) ==
+ CON_IC_STATUS_CONNECTED;
+}
+
+static void
+_connection_init(MafwGstRenderer *renderer)
+{
+ g_assert (MAFW_IS_GST_RENDERER(renderer));
+
+ if (renderer->connection == NULL) {
+ renderer->connection = con_ic_connection_new();
+ renderer->connected = FALSE;
+
+ g_assert(renderer->connection != NULL);
+ }
+
+ g_object_set(renderer->connection, "automatic-connection-events",
+ TRUE, NULL);
+ g_signal_connect(renderer->connection, "connection-event",
+ G_CALLBACK (_con_ic_status_handler), renderer);
+
+ con_ic_connection_connect(renderer->connection,
+ CON_IC_CONNECT_FLAG_AUTOMATICALLY_TRIGGERED);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ Hal callbacks
+ ----------------------------------------------------------------------------*/
+
+static gboolean _tv_out_is_connected(LibHalContext *ctx, const char *udi)
+{
+ gboolean is_tv_out_jack = FALSE;
+ char **jack_types;
+ char **jack;
+
+ if (udi == NULL) {
+ return FALSE;
+ }
+
+ jack_types = libhal_device_get_property_strlist(ctx, udi,
+ "input.jack.type",
+ NULL);
+ if (jack_types == NULL) {
+ return FALSE;
+ }
+
+ jack = jack_types;
+ while (*jack) {
+ if (strcmp(*jack, "video-out") == 0) {
+ is_tv_out_jack = TRUE;
+ break;
+ } else {
+ jack++;
+ }
+ }
+
+ libhal_free_string_array(jack_types);
+
+ return is_tv_out_jack;
+}
+
+static void _property_modified(LibHalContext *ctx, const char *udi,
+ const char *key, dbus_bool_t is_removed,
+ dbus_bool_t is_added)
+{
+ MafwGstRenderer *renderer;
+ gboolean connected;
+ GValue value = { 0 };
+
+ g_debug("HAL property modified! jack changed\n");
+ connected = _tv_out_is_connected(ctx, udi);
+ renderer = MAFW_GST_RENDERER(libhal_ctx_get_user_data(ctx));
+ if (renderer->tv_connected != connected) {
+ /* Notify the change */
+ renderer->tv_connected = connected;
+ g_value_init(&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean(&value, renderer->tv_connected);
+ mafw_extension_emit_property_changed(
+ MAFW_EXTENSION(renderer),
+ MAFW_PROPERTY_GST_RENDERER_TV_CONNECTED,
+ &value);
+ g_value_unset(&value);
+ }
+ blanking_control(connected == FALSE);
+}
+
+/*----------------------------------------------------------------------------
+ GConf notifications
+ ----------------------------------------------------------------------------*/
+
+static void _battery_cover_open_cb(GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ MafwGstRenderer *renderer)
+{
+ GConfValue *value = NULL;
+ gboolean is_cover_open;
+
+ value = gconf_entry_get_value(entry);
+ is_cover_open = gconf_value_get_bool(value);
+
+ if (is_cover_open) {
+ /* External mmc could be removed!. */
+ const gchar *emmc_path = g_getenv("MMC_MOUNTPOINT");
+
+ mafw_gst_renderer_state_handle_pre_unmount(
+ MAFW_GST_RENDERER_STATE(
+ renderer->states[renderer->current_state]),
+ emmc_path);
+ }
+}
+
+static void _autoload_subtitles_changed_cb(GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ MafwGstRenderer *renderer)
+{
+ GConfValue *value = NULL;
+ gboolean enabled = FALSE;
+
+ value = gconf_entry_get_value(entry);
+ if (value == NULL)
+ return;
+
+ enabled = gconf_value_get_bool(value);
+
+ if (enabled)
+ renderer->worker->subtitles.enabled = TRUE;
+ else
+ renderer->worker->subtitles.enabled = FALSE;
+}
+
+static void _subtitle_font_changed_cb(GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ MafwGstRenderer *renderer)
+{
+ const gchar *key = NULL;
+ GConfValue *value = NULL;
+ const gchar *str_value = NULL;
+
+ key = gconf_entry_get_key(entry);
+
+ /* Only key without absolute path is required */
+ key += strlen(GCONF_MAFW_GST_SUBTITLES_RENDERER) + 1;
+
+ value = gconf_entry_get_value(entry);
+ if (value)
+ str_value = gconf_value_get_string(value);
+ else
+ str_value = NULL;
+
+ if (strcmp(key, "subtitle_font") == 0) {
+ if (renderer->worker->subtitles.font)
+ g_free(renderer->worker->subtitles.font);
+
+ if (str_value)
+ renderer->worker->subtitles.font = g_strdup(str_value);
+ else
+ renderer->worker->subtitles.font = NULL;
+ } else if (strcmp(key, "subtitle_encoding") == 0) {
+ if (renderer->worker->subtitles.encoding)
+ g_free(renderer->worker->subtitles.encoding);
+
+ if (str_value)
+ renderer->worker->subtitles.encoding = g_strdup(str_value);
+ else
+ renderer->worker->subtitles.encoding = NULL;
+ } else {
+ g_warning("Wrong %s key, %s", GCONF_MAFW_GST_SUBTITLES_RENDERER, key);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Gnome VFS notifications
+ ----------------------------------------------------------------------------*/
+
+static void _volume_pre_unmount_cb(GnomeVFSVolumeMonitor *monitor,
+ GnomeVFSVolume *volume,
+ MafwGstRenderer *renderer)
+{
+ gchar *location = gnome_vfs_volume_get_activation_uri(volume);
+ if (!location) {
+ return;
+ }
+
+ mafw_gst_renderer_state_handle_pre_unmount(
+ MAFW_GST_RENDERER_STATE(
+ renderer->states[renderer->current_state]),
+ location);
+
+ g_free(location);
+}
+
+/*----------------------------------------------------------------------------
+ Signals
+ ----------------------------------------------------------------------------*/
+
+
+/**
+ * _signal_state_changed:
+ * @self: A #MafwGstRenderer
+ *
+ * Signals state_changed to all UIs
+ **/
+static void _signal_state_changed(MafwGstRenderer * self)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_signal_emit_by_name(MAFW_RENDERER(self),
+ "state-changed", self->current_state);
+}
+
+/**
+ * _signal_playlist_changed:
+ * @self: A #MafwGstRenderer
+ *
+ * Signals playlist update to all UIs
+ **/
+static void _signal_playlist_changed(MafwGstRenderer * self)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_signal_emit_by_name(MAFW_RENDERER(self),
+ "playlist-changed", self->playlist);
+}
+
+/**
+ * _signal_media_changed:
+ * @self: A #MafwGstRenderer
+ *
+ * Signals media_changed to all UIs
+ **/
+static void _signal_media_changed(MafwGstRenderer *self)
+{
+
+ MafwGstRendererPlaybackMode mode;
+ gint index;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ mode = mafw_gst_renderer_get_playback_mode(MAFW_GST_RENDERER(self));
+ if ((mode == MAFW_GST_RENDERER_MODE_STANDALONE) ||
+ (self->iterator == NULL)) {
+ index = -1;
+ } else {
+ index = mafw_playlist_iterator_get_current_index(self->iterator);
+ }
+
+ g_signal_emit_by_name(MAFW_RENDERER(self),
+ "media-changed",
+ index,
+ self->media->object_id);
+}
+
+/**
+ * _signal_transport_actions_property_changed:
+ * @self: A #MafwGstRenderer
+ *
+ * Signals transport_actions property_changed to all UIs
+ **/
+static void _signal_transport_actions_property_changed(MafwGstRenderer * self)
+{
+ GValue *value;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ value = mafw_gst_renderer_state_get_property_value(
+ MAFW_GST_RENDERER_STATE(
+ self->states[self->current_state]),
+ MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS);
+
+ if (value) {
+ mafw_extension_emit_property_changed(
+ MAFW_EXTENSION(self),
+ MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS,
+ value);
+ g_value_unset(value);
+ g_free(value);
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ State pattern support
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_set_state(MafwGstRenderer *self, MafwPlayState state)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ self->current_state = state;
+ _signal_state_changed(self);
+ _signal_transport_actions_property_changed(self);
+}
+
+void mafw_gst_renderer_play(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer*) self;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ mafw_gst_renderer_state_play(
+ MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
+ &error);
+
+ if (callback != NULL)
+ callback(self, user_data, error);
+ if (error)
+ g_error_free(error);
+}
+
+void mafw_gst_renderer_play_object(MafwRenderer *self,
+ const gchar *object_id,
+ MafwRendererPlaybackCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer*) self;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+ g_return_if_fail(object_id != NULL);
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ mafw_gst_renderer_state_play_object(
+ MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
+ object_id,
+ &error);
+
+ if (callback != NULL)
+ callback(self, user_data, error);
+ if (error)
+ g_error_free(error);
+}
+
+void mafw_gst_renderer_stop(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer *) self;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ renderer->play_failed_count = 0;
+ mafw_gst_renderer_state_stop(
+ MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
+ &error);
+
+ if (callback != NULL)
+ callback(self, user_data, error);
+ if (error)
+ g_error_free(error);
+}
+
+
+void mafw_gst_renderer_pause(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer *) self;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ mafw_gst_renderer_state_pause(
+ MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
+ &error);
+
+ if (callback != NULL)
+ callback(self, user_data, error);
+ if (error)
+ g_error_free(error);
+}
+
+void mafw_gst_renderer_resume(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer *) self;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ mafw_gst_renderer_state_resume(
+ MAFW_GST_RENDERER_STATE (renderer->states[renderer->current_state]),
+ &error);
+
+ if (callback != NULL)
+ callback(self, user_data, error);
+ if (error)
+ g_error_free(error);
+}
+
+void mafw_gst_renderer_next(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer *) self;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ renderer->play_failed_count = 0;
+ mafw_gst_renderer_state_next(
+ MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
+ &error);
+
+ if (callback != NULL)
+ callback(self, user_data, error);
+ if (error)
+ g_error_free(error);
+}
+
+void mafw_gst_renderer_previous(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer *) self;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ renderer->play_failed_count = 0;
+ mafw_gst_renderer_state_previous(
+ MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
+ &error);
+
+ if (callback != NULL)
+ callback(self, user_data, error);
+ if (error)
+ g_error_free(error);
+}
+
+void mafw_gst_renderer_goto_index(MafwRenderer *self, guint index,
+ MafwRendererPlaybackCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer *) self;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ renderer->play_failed_count = 0;
+ mafw_gst_renderer_state_goto_index(
+ MAFW_GST_RENDERER_STATE(renderer->states[renderer->current_state]),
+ index,
+ &error);
+
+ if (callback != NULL)
+ callback(self, user_data, error);
+ if (error)
+ g_error_free(error);
+}
+
+void mafw_gst_renderer_get_position(MafwRenderer *self, MafwRendererPositionCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer;
+ gint pos;
+ GError *error = NULL;
+
+ g_return_if_fail(callback != NULL);
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ renderer = MAFW_GST_RENDERER(self);
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ mafw_gst_renderer_state_get_position(
+ MAFW_GST_RENDERER_STATE (renderer->states[renderer->current_state]),
+ &pos,
+ &error);
+
+ callback(self, pos, user_data, error);
+ if (error)
+ g_error_free(error);
+}
+
+void mafw_gst_renderer_set_position(MafwRenderer *self, MafwRendererSeekMode mode,
+ gint seconds, MafwRendererPositionCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer *) self;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ mafw_gst_renderer_state_set_position(
+ MAFW_GST_RENDERER_STATE (renderer->states[renderer->current_state]),
+ mode,
+ seconds,
+ &error);
+
+ if (callback != NULL)
+ callback(self, seconds, user_data, error);
+ if (error)
+ g_error_free(error);
+}
+
+gboolean mafw_gst_renderer_manage_error_idle(gpointer data)
+{
+ MafwGstRendererErrorClosure *mec = (MafwGstRendererErrorClosure *) data;
+
+ mafw_gst_renderer_manage_error(mec->renderer, mec->error);
+ if (mec->error)
+ g_error_free(mec->error);
+ g_free(mec);
+
+ return FALSE;
+}
+
+static void _run_error_policy(MafwGstRenderer *self, const GError *in_err,
+ GError **out_err)
+{
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ gboolean play_next = FALSE;
+
+ /* Check what to do on error */
+ if (in_err->code == MAFW_EXTENSION_ERROR_OUT_OF_MEMORY) {
+ play_next = FALSE;
+ } else {
+ MafwGstRendererPlaybackMode mode;
+
+ mode = mafw_gst_renderer_get_playback_mode(self);
+
+ if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST) {
+ /* In playlist mode we try to play next if
+ error policy suggests so */
+ play_next =
+ (_get_error_policy(self) ==
+ MAFW_RENDERER_ERROR_POLICY_CONTINUE);
+ } else {
+ /* In standalone mode, then switch back to playlist
+ mode and resume if necessary or move to Stopped
+ otherwise */
+ mafw_gst_renderer_set_playback_mode(
+ self, MAFW_GST_RENDERER_MODE_PLAYLIST);
+ mafw_gst_renderer_set_media_playlist(self);
+ if (self->resume_playlist) {
+ mafw_gst_renderer_play(MAFW_RENDERER(self),
+ NULL, NULL);
+ } else {
+ mafw_gst_renderer_worker_stop(self->worker);
+ mafw_gst_renderer_set_state(self, Stopped);
+ }
+ if (out_err) *out_err = g_error_copy(in_err);
+
+ /* Bail out, he have already managed the error
+ for the case of standalone mode */
+ return;
+ }
+ }
+
+ if (play_next) {
+ if (self->playlist){
+ MafwPlaylistIteratorMovementResult result;
+
+ result = mafw_playlist_iterator_move_to_next(self->iterator,
+ NULL);
+ self->play_failed_count++;
+
+ if (mafw_playlist_iterator_get_size(self->iterator,
+ NULL) <=
+ self->play_failed_count)
+ {
+ mafw_gst_renderer_state_stop(
+ MAFW_GST_RENDERER_STATE(self->states[self->current_state]),
+ NULL);
+ self->play_failed_count = 0;
+ mafw_gst_renderer_set_media_playlist(self);
+ } else if (result !=
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK) {
+ mafw_playlist_iterator_reset(self->iterator, NULL);
+ mafw_gst_renderer_set_media_playlist(self);
+ mafw_gst_renderer_stop(MAFW_RENDERER(self), NULL, NULL);
+ } else {
+ mafw_gst_renderer_set_media_playlist(self);
+ mafw_gst_renderer_play(MAFW_RENDERER(self), NULL, NULL);
+ }
+
+ if (out_err) *out_err = g_error_copy(in_err);
+ }
+ } else {
+ /* We cannot move to next in the playlist or decided
+ we do not want to do it, just stop on error */
+ mafw_gst_renderer_stop(MAFW_RENDERER(self), NULL, NULL);
+ if (out_err) *out_err = g_error_copy(in_err);
+ }
+}
+
+static void _metadata_set_cb(MafwSource *self, const gchar *object_id,
+ const gchar **failed_keys, gpointer user_data,
+ const GError *error)
+{
+ if (error != NULL) {
+ g_debug("Ignoring error received when setting metadata: "
+ "%s (%d): %s", g_quark_to_string(error->domain),
+ error->code, error->message);
+ } else {
+ g_debug("Metadata set correctly");
+ }
+}
+
+/**
+ * _update_playcount_metadata_cb:
+ * @cb_source: The #MafwSource that sent the metadata results
+ * @cb_object_id: The object ID, whose metadata results were received
+ * @cb_metadata: GHashTable containing metadata key-value pairs
+ * @cb_user_data: Optional user data pointer (self)
+ * @cb_error: Set if any errors occurred during metadata browsing
+ *
+ * Receives the results of a metadata request about the playcount. It increases
+ * it, or sets to 1, and sets the metadata to that.
+ */
+static void _update_playcount_metadata_cb (MafwSource *cb_source,
+ const gchar *cb_object_id,
+ GHashTable *cb_metadata,
+ gpointer cb_user_data,
+ const GError *cb_error)
+{
+ GValue *curval = NULL;
+ gint curplaycount = -1;
+ GHashTable *mdata = cb_user_data;
+
+ if (cb_error == NULL) {
+ if (cb_metadata)
+ curval = mafw_metadata_first(cb_metadata,
+ MAFW_METADATA_KEY_PLAY_COUNT);
+ if (curval && !G_VALUE_HOLDS(curval, G_TYPE_INT))
+ goto set_data;
+ if (curval)
+ {
+ curplaycount = g_value_get_int(curval);
+ curplaycount++;
+ }
+ else
+ { /* Playing at first time, or not supported... */
+ curplaycount = 1;
+ }
+ if (!mdata)
+ mdata = mafw_metadata_new();
+ mafw_metadata_add_int(mdata,
+ MAFW_METADATA_KEY_PLAY_COUNT,
+ curplaycount);
+
+ } else {
+ g_warning("_playcount_metadata received an error: "
+ "%s (%d): %s", g_quark_to_string(cb_error->domain),
+ cb_error->code, cb_error->message);
+ if (mdata)
+ g_hash_table_unref(mdata);
+ return;
+ }
+set_data:
+
+ if (mdata)
+ {
+ mafw_source_set_metadata(cb_source, cb_object_id, mdata,
+ _metadata_set_cb, NULL);
+ g_hash_table_unref(mdata);
+ }
+}
+
+/**
+ * mafw_gst_renderer_add_lastplayed:
+ * @mdata: Exisiting mdata, or NULL
+ *
+ * Sets the MAFW_METADATA_KEY_LAST_PLAYED metadata in the given metadata-table,
+ * or creates a new metadata-table, and sets the current time there.
+ */
+static GHashTable *mafw_gst_renderer_add_lastplayed(GHashTable *mdata)
+{
+ GHashTable *metadata;
+ GTimeVal timeval;
+
+
+ if (!mdata)
+ metadata = mafw_metadata_new();
+ else
+ metadata = mdata;
+
+
+
+ g_get_current_time(&timeval);
+
+ mafw_metadata_add_long(metadata,
+ MAFW_METADATA_KEY_LAST_PLAYED,
+ timeval.tv_sec);
+ return metadata;
+}
+
+/**
+ * mafw_gst_renderer_increase_playcount:
+ * @self: Gst renderer
+ * @object_id: The object ID of the touched object
+ * @mdat: Existing metadatas to add the playcount to, or NULL
+ *
+ * Increases the playcount of the given object.
+ */
+static void mafw_gst_renderer_increase_playcount(MafwGstRenderer* self,
+ const gchar *object_id, GHashTable *mdat)
+{
+ MafwSource* source;
+
+ g_assert(self != NULL);
+ source = _get_source(self, object_id);
+ if (source != NULL)
+ {
+ static const gchar * const keys[] =
+ { MAFW_METADATA_KEY_PLAY_COUNT, NULL };
+
+ mafw_source_get_metadata(source, object_id,
+ keys,
+ _update_playcount_metadata_cb,
+ mdat);
+
+ }
+}
+
+/**
+ * mafw_gst_renderer_update_stats:
+ * @data: user data
+ *
+ * Updates both playcount and lastplayed after a while.
+ **/
+gboolean mafw_gst_renderer_update_stats(gpointer data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer *) data;
+
+ /* Update stats only for audio content */
+ if (renderer->media->object_id &&
+ !renderer->worker->media.has_visual_content) {
+ GHashTable *mdata = mafw_gst_renderer_add_lastplayed(NULL);
+ mafw_gst_renderer_increase_playcount(renderer,
+ renderer->media->object_id,
+ mdata);
+ }
+ renderer->update_playcount_id = 0;
+ return FALSE;
+}
+
+void mafw_gst_renderer_update_source_duration(MafwGstRenderer *renderer,
+ gint duration)
+{
+ GHashTable *metadata;
+ MafwSource* source;
+
+ source = _get_source(renderer, renderer->media->object_id);
+ g_return_if_fail(source != NULL);
+
+ renderer->media->duration = duration;
+
+ g_debug("updated source duration to %d", duration);
+
+ metadata = mafw_metadata_new();
+ mafw_metadata_add_int(metadata, MAFW_METADATA_KEY_DURATION, duration);
+
+ mafw_source_set_metadata(source, renderer->media->object_id, metadata,
+ _metadata_set_cb, NULL);
+ g_hash_table_unref(metadata);
+}
+
+/**
+ * _notify_metadata:
+ * @source: The #MafwSource that sent the metadata results
+ * @objectid: The object ID, whose metadata results were received
+ * @metadata: GHashTable containing metadata key-value pairs
+ * @userdata: Optional user data pointer (self)
+ * @error: Set if any errors occurred during metadata browsing
+ *
+ * Receives the results of a metadata request.
+ */
+static void _notify_metadata (MafwSource *cb_source,
+ const gchar *cb_object_id,
+ GHashTable *cb_metadata,
+ gpointer cb_user_data,
+ const GError *cb_error)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer*) cb_user_data;
+ GError *mafw_error = NULL;
+ GError *error = NULL;
+ GValue *mval;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(renderer));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ g_debug("running _notify_metadata...");
+
+ mval = mafw_metadata_first(cb_metadata, MAFW_METADATA_KEY_URI);
+
+ if (cb_error == NULL && mval != NULL) {
+ mafw_gst_renderer_state_notify_metadata(
+ MAFW_GST_RENDERER_STATE(
+ renderer->states[renderer->current_state]),
+ cb_object_id,
+ cb_metadata,
+ &error);
+ }
+ else {
+ g_set_error(&mafw_error,
+ MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_URI_NOT_AVAILABLE, "%s",
+ cb_error ? cb_error->message : "URI not available");
+ mafw_gst_renderer_manage_error(renderer, mafw_error);
+ g_error_free(mafw_error);
+ }
+}
+
+static void _notify_play(MafwGstRendererWorker *worker, gpointer owner)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer*) owner;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(renderer));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ g_debug("running _notify_play...");
+
+ mafw_gst_renderer_state_notify_play(renderer->states[renderer->current_state],
+ &error);
+
+ if (error != NULL) {
+ g_signal_emit_by_name(MAFW_EXTENSION (renderer), "error",
+ error->domain,
+ error->code,
+ error->message);
+ g_error_free (error);
+ }
+}
+
+static void _notify_pause(MafwGstRendererWorker *worker, gpointer owner)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer*) owner;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER (renderer));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ mafw_gst_renderer_state_notify_pause(renderer->states[renderer->current_state],
+ &error);
+
+ if (error != NULL) {
+ g_signal_emit_by_name(MAFW_EXTENSION (renderer), "error",
+ error->domain, error->code,
+ error->message);
+ g_error_free(error);
+ }
+}
+
+static void _notify_buffer_status (MafwGstRendererWorker *worker,
+ gpointer owner,
+ gdouble percent)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer*) owner;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(renderer));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ mafw_gst_renderer_state_notify_buffer_status(
+ renderer->states[renderer->current_state],
+ percent,
+ &error);
+
+ if (error != NULL) {
+ g_signal_emit_by_name(MAFW_EXTENSION (renderer), "error",
+ error->domain, error->code,
+ error->message);
+ g_error_free(error);
+ }
+}
+
+static void _notify_seek(MafwGstRendererWorker *worker, gpointer owner)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer*) owner;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(renderer));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ mafw_gst_renderer_state_notify_seek(renderer->states[renderer->current_state],
+ &error);
+
+ if (error != NULL) {
+ g_signal_emit_by_name(MAFW_EXTENSION(renderer), "error",
+ error->domain, error->code,
+ error->message);
+ g_error_free(error);
+ }
+}
+
+static void _playlist_changed_handler(MafwPlaylistIterator *iterator,
+ gboolean clip_changed, GQuark domain,
+ gint code, const gchar *message,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer*) user_data;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(renderer));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ /* We update the current index and media here, for this is
+ the same for all the states. Then we delegate in the state
+ to finish the task (for example, start playback if needed) */
+
+ if (renderer->playlist == NULL) {
+ g_critical("Got iterator:contents-changed but renderer has no" \
+ "playlist assigned!. Skipping...");
+ return;
+ }
+
+ if (domain != 0) {
+ g_signal_emit_by_name(MAFW_EXTENSION(renderer), "error",
+ domain, code, message);
+ } else {
+ GError *error = NULL;
+ MafwGstRendererPlaybackMode mode;
+
+ mode = mafw_gst_renderer_get_playback_mode(renderer);
+
+ /* Only in non-playobject mode */
+ if (clip_changed && mode == MAFW_GST_RENDERER_MODE_PLAYLIST)
+ mafw_gst_renderer_set_media_playlist(renderer);
+
+ /* We let the state know if the current clip has changed as
+ result of this operation, so it can do its work */
+ mafw_gst_renderer_state_playlist_contents_changed_handler(
+ renderer->states[renderer->current_state],
+ clip_changed,
+ &error);
+
+ if (error != NULL) {
+ g_signal_emit_by_name(MAFW_EXTENSION(renderer), "error",
+ error->domain, error->code,
+ error->message);
+ g_error_free(error);
+ }
+ }
+}
+
+static void _error_handler(MafwGstRendererWorker *worker, gpointer owner,
+ const GError *error)
+{
+ MafwGstRenderer *renderer = MAFW_GST_RENDERER(owner);
+
+ mafw_gst_renderer_manage_error(renderer, error);
+}
+
+void mafw_gst_renderer_manage_error(MafwGstRenderer *self, const GError *error)
+{
+ GError *new_err = NULL;
+ GError *raise_error = NULL;
+ GQuark new_err_domain = MAFW_RENDERER_ERROR;
+ gint new_err_code = 0;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+
+ g_return_if_fail((self->states != 0) &&
+ (self->current_state != _LastMafwPlayState) &&
+ (self->states[self->current_state] != NULL));
+
+ g_warning("Got error in renderer:\n\tdomain: %d, code: %d, message: %s",
+ error->domain, error->code, error->message);
+
+ /* Get a MAFW error */
+ if (error->domain == GST_RESOURCE_ERROR) {
+ /* handle RESOURCE errors */
+ switch (error->code) {
+ case GST_RESOURCE_ERROR_READ:
+ if (is_current_uri_stream(self)) {
+#ifdef HAVE_CONIC
+ if (self->connected) {
+ new_err_code = MAFW_RENDERER_ERROR_STREAM_DISCONNECTED;
+ } else {
+ new_err_domain = MAFW_EXTENSION_ERROR;
+ new_err_code = MAFW_EXTENSION_ERROR_NETWORK_DOWN;
+ }
+#else
+ /* Stream + cannot read resource ->
+ disconnected */
+ new_err_code = MAFW_RENDERER_ERROR_STREAM_DISCONNECTED;
+#endif
+ } else {
+ /* This shouldn't happen */
+ /* Unknown RESOURCE error */
+ new_err_domain = MAFW_EXTENSION_ERROR;
+ new_err_code = MAFW_EXTENSION_ERROR_FAILED;
+ }
+ break;
+ case GST_RESOURCE_ERROR_NOT_FOUND:
+#ifdef HAVE_CONIC
+ if (!is_current_uri_stream(self) || self->connected) {
+ new_err_code =
+ MAFW_RENDERER_ERROR_INVALID_URI;
+ } else {
+ new_err_domain = MAFW_EXTENSION_ERROR;
+ new_err_code = MAFW_EXTENSION_ERROR_NETWORK_DOWN;
+ }
+#else
+ new_err_code =
+ MAFW_RENDERER_ERROR_INVALID_URI;
+#endif
+ break;
+ case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
+ case GST_RESOURCE_ERROR_OPEN_READ:
+#ifdef HAVE_CONIC
+ if (!is_current_uri_stream(self) || self->connected) {
+ new_err_code =
+ MAFW_RENDERER_ERROR_MEDIA_NOT_FOUND;
+ } else {
+ new_err_domain = MAFW_EXTENSION_ERROR;
+ new_err_code = MAFW_EXTENSION_ERROR_NETWORK_DOWN;
+ }
+#else
+ new_err_code =
+ MAFW_RENDERER_ERROR_MEDIA_NOT_FOUND;
+#endif
+ break;
+ case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
+ new_err_domain = MAFW_EXTENSION_ERROR;
+ new_err_code = MAFW_EXTENSION_ERROR_OUT_OF_MEMORY;
+ break;
+ case GST_RESOURCE_ERROR_WRITE:
+ /* DSP renderers send ERROR_WRITE when they find
+ corrupted data */
+ new_err_code = MAFW_RENDERER_ERROR_CORRUPTED_FILE;
+ break;
+ case GST_RESOURCE_ERROR_SEEK:
+ new_err_code = MAFW_RENDERER_ERROR_CANNOT_SET_POSITION;
+ break;
+ default:
+ /* Unknown RESOURCE error */
+ new_err_domain = MAFW_EXTENSION_ERROR;
+ new_err_code = MAFW_EXTENSION_ERROR_FAILED;
+ }
+
+ } else if (error->domain == GST_STREAM_ERROR) {
+ /* handle STREAM errors */
+ switch (error->code) {
+ case GST_STREAM_ERROR_TYPE_NOT_FOUND:
+ new_err_code = MAFW_RENDERER_ERROR_TYPE_NOT_AVAILABLE;
+ break;
+ case GST_STREAM_ERROR_FORMAT:
+ case GST_STREAM_ERROR_WRONG_TYPE:
+ case GST_STREAM_ERROR_FAILED:
+ new_err_code = MAFW_RENDERER_ERROR_UNSUPPORTED_TYPE;
+ break;
+ case GST_STREAM_ERROR_DECODE:
+ case GST_STREAM_ERROR_DEMUX:
+ new_err_code = MAFW_RENDERER_ERROR_CORRUPTED_FILE;
+ break;
+ case GST_STREAM_ERROR_CODEC_NOT_FOUND:
+ new_err_code = MAFW_RENDERER_ERROR_CODEC_NOT_FOUND;
+ break;
+ case GST_STREAM_ERROR_DECRYPT:
+ case GST_STREAM_ERROR_DECRYPT_NOKEY:
+ new_err_code = MAFW_RENDERER_ERROR_DRM;
+ break;
+ default:
+ /* Unknown STREAM error */
+ new_err_domain = MAFW_EXTENSION_ERROR;
+ new_err_code = MAFW_EXTENSION_ERROR_FAILED;
+ }
+ } else if (error->domain == MAFW_GST_RENDERER_ERROR) {
+ /* Handle own errors. Errors that belong to this domain:
+ - MAFW_GST_RENDERER_ERROR_PLUGIN_NOT_FOUND,
+ - MAFW_GST_RENDERER_ERROR_VIDEO_CODEC_NOT_SUPPORTED,
+ - MAFW_GST_RENDERER_ERROR_AUDIO_CODEC_NOT_SUPPORTED */
+ new_err_code = MAFW_RENDERER_ERROR_UNSUPPORTED_TYPE;
+ } else if (error->domain == MAFW_RENDERER_ERROR) {
+ /* Worker may have sent MAFW_RENDERER_ERROR as well.
+ No processing needed */
+ new_err_code = error->code;
+ } else {
+ /* default */
+ /* Unknown error */
+ new_err_domain = MAFW_EXTENSION_ERROR;
+ new_err_code = MAFW_EXTENSION_ERROR_FAILED;
+ }
+
+ g_set_error(&new_err, new_err_domain, new_err_code, "%s", error->message);
+
+ _run_error_policy(self, new_err, &raise_error);
+ g_error_free(new_err);
+
+ if (raise_error) {
+ g_signal_emit_by_name(MAFW_EXTENSION (self), "error",
+ raise_error->domain,
+ raise_error->code,
+ raise_error->message);
+ g_error_free(raise_error);
+ }
+}
+
+static void _notify_eos(MafwGstRendererWorker *worker, gpointer owner)
+{
+ MafwGstRenderer *renderer = (MafwGstRenderer*) owner;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER (renderer));
+
+ g_return_if_fail((renderer->states != 0) &&
+ (renderer->current_state != _LastMafwPlayState) &&
+ (renderer->states[renderer->current_state] != NULL));
+
+ mafw_gst_renderer_state_notify_eos(renderer->states[renderer->current_state],
+ &error);
+
+ if (error != NULL) {
+ g_signal_emit_by_name(MAFW_EXTENSION(renderer), "error",
+ error->domain, error->code,
+ error->message);
+ g_error_free(error);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Status
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_get_status(MafwRenderer *self, MafwRendererStatusCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer* renderer;
+ gint index;
+ MafwGstRendererPlaybackMode mode;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+ g_return_if_fail(callback != NULL);
+ renderer = MAFW_GST_RENDERER(self);
+
+ mode = mafw_gst_renderer_get_playback_mode(MAFW_GST_RENDERER(self));
+ if ((mode == MAFW_GST_RENDERER_MODE_STANDALONE) || (renderer->iterator == NULL)) {
+ index = -1;
+ } else {
+ index =
+ mafw_playlist_iterator_get_current_index(renderer->iterator);
+ }
+
+ /* TODO: Set error parameter */
+ callback(self, renderer->playlist, index, renderer->current_state,
+ (const gchar*) renderer->media->object_id, user_data, NULL);
+}
+
+void mafw_gst_renderer_get_current_metadata(MafwRenderer *self,
+ MafwRendererMetadataResultCB callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer;
+ GHashTable *metadata;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+ renderer = MAFW_GST_RENDERER(self);
+
+ metadata = mafw_gst_renderer_worker_get_current_metadata(
+ renderer->worker);
+
+ callback(self,
+ (const gchar*) renderer->media->object_id,
+ metadata,
+ user_data,
+ NULL);
+}
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+static void
+_playlist_contents_changed_handler(MafwPlaylist *playlist,
+ guint from, guint nremove,
+ guint nreplace,
+ MafwGstRenderer *renderer)
+{
+ /* Item(s) added to playlist, so new playable items could come */
+ if (nreplace)
+ renderer->play_failed_count = 0;
+}
+
+gboolean mafw_gst_renderer_assign_playlist(MafwRenderer *self,
+ MafwPlaylist *playlist,
+ GError **error)
+{
+ MafwGstRenderer* renderer = (MafwGstRenderer*) self;
+
+ g_return_val_if_fail(MAFW_IS_GST_RENDERER(self), FALSE);
+
+ /* Get rid of previously assigned playlist */
+ if (renderer->playlist != NULL) {
+ g_signal_handlers_disconnect_matched(renderer->iterator,
+ (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ _playlist_changed_handler,
+ NULL);
+ g_signal_handlers_disconnect_matched(renderer->playlist,
+ (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ G_CALLBACK(_playlist_contents_changed_handler),
+ NULL);
+ /* Decrement the use count of the previous playlist because the
+ renderer isn't going to use it more */
+ mafw_playlist_decrement_use_count(renderer->playlist, NULL);
+
+ g_object_unref(renderer->iterator);
+ g_object_unref(renderer->playlist);
+ }
+
+ /* Assign the new playlist */
+ if (playlist == NULL) {
+ renderer->playlist = NULL;
+ renderer->iterator = NULL;
+ } else {
+ GError *new_error = NULL;
+ MafwPlaylistIterator *iterator = NULL;
+
+ iterator = mafw_playlist_iterator_new();
+ mafw_playlist_iterator_initialize(iterator, playlist,
+ &new_error);
+
+ g_object_ref(playlist);
+
+ if (new_error == NULL) {
+
+ renderer->playlist = playlist;
+ renderer->iterator = iterator;
+
+ /* Increment the use_count to avoid the playlist destruction
+ while the playlist is assigned to some renderer */
+ mafw_playlist_increment_use_count(renderer->playlist, NULL);
+
+ g_signal_connect(iterator,
+ "playlist-changed",
+ G_CALLBACK(_playlist_changed_handler),
+ renderer);
+ g_signal_connect(renderer->playlist,
+ "contents-changed",
+ G_CALLBACK(_playlist_contents_changed_handler),
+ renderer);
+ }
+ else {
+ g_propagate_error (error, new_error);
+ }
+ }
+
+ /* Set the new media and signal playlist changed signal */
+ _signal_playlist_changed(renderer);
+ mafw_gst_renderer_set_media_playlist(renderer);
+
+
+ /* Stop playback */
+ mafw_gst_renderer_stop(MAFW_RENDERER(renderer), NULL , NULL);
+
+ return TRUE;
+}
+
+MafwGstRendererMovementResult mafw_gst_renderer_move(MafwGstRenderer *renderer,
+ MafwGstRendererMovementType type,
+ guint index,
+ GError **error)
+{
+ MafwGstRendererMovementResult value = MAFW_GST_RENDERER_MOVE_RESULT_OK;
+
+ if (renderer->playlist == NULL) {
+ value = MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST;
+ } else {
+ MafwPlaylistIteratorMovementResult result;
+
+ switch (type) {
+ case MAFW_GST_RENDERER_MOVE_TYPE_INDEX:
+ result =
+ mafw_playlist_iterator_move_to_index(renderer->iterator,
+ index,
+ error);
+ break;
+ case MAFW_GST_RENDERER_MOVE_TYPE_PREV:
+ result =
+ mafw_playlist_iterator_move_to_prev(renderer->iterator,
+ error);
+ break;
+ case MAFW_GST_RENDERER_MOVE_TYPE_NEXT:
+ result =
+ mafw_playlist_iterator_move_to_next(renderer->iterator,
+ error);
+ break;
+ }
+
+ switch (result) {
+ case MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK:
+ value = MAFW_GST_RENDERER_MOVE_RESULT_OK;
+ mafw_gst_renderer_set_media_playlist(renderer);
+ break;
+ case MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_INVALID:
+ g_critical("Iterator is invalid!");
+ value = MAFW_GST_RENDERER_MOVE_RESULT_ERROR;
+ break;
+ case MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR:
+ value = MAFW_GST_RENDERER_MOVE_RESULT_ERROR;
+ break;
+ case MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_LIMIT:
+ value = MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT;
+ break;
+ }
+ }
+
+ return value;
+}
+
+/*----------------------------------------------------------------------------
+ Properties
+ ----------------------------------------------------------------------------*/
+
+static void _set_error_policy(MafwGstRenderer *renderer, MafwRendererErrorPolicy policy)
+{
+ renderer->error_policy = policy;
+}
+
+static MafwRendererErrorPolicy _get_error_policy(MafwGstRenderer *renderer)
+{
+ return renderer->error_policy;
+}
+
+static void mafw_gst_renderer_get_property(MafwExtension *self,
+ const gchar *key,
+ MafwExtensionPropertyCallback callback,
+ gpointer user_data)
+{
+ MafwGstRenderer *renderer;
+ GValue *value = NULL;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+ g_return_if_fail(callback != NULL);
+ g_return_if_fail(key != NULL);
+
+ renderer = MAFW_GST_RENDERER(self);
+ if (!strcmp(key, MAFW_PROPERTY_RENDERER_VOLUME)) {
+ guint volume;
+
+ volume = mafw_gst_renderer_worker_get_volume(
+ renderer->worker);
+
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_UINT);
+ g_value_set_uint(value, volume);
+ }
+ else if (!strcmp(key, MAFW_PROPERTY_RENDERER_MUTE)) {
+ gboolean mute;
+ mute = mafw_gst_renderer_worker_get_mute(renderer->worker);
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_BOOLEAN);
+ g_value_set_boolean(value, mute);
+ }
+ else if (!strcmp (key, MAFW_PROPERTY_RENDERER_XID)) {
+ guint xid;
+ xid = mafw_gst_renderer_worker_get_xid(renderer->worker);
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_UINT);
+ g_value_set_uint(value, xid);
+ }
+ else if (!strcmp(key, MAFW_PROPERTY_RENDERER_ERROR_POLICY)) {
+ guint policy;
+ policy = _get_error_policy(renderer);
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_UINT);
+ g_value_set_uint(value, policy);
+ }
+ else if (!strcmp(key, MAFW_PROPERTY_RENDERER_AUTOPAINT)) {
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_BOOLEAN);
+ g_value_set_boolean(
+ value,
+ mafw_gst_renderer_worker_get_autopaint(
+ renderer->worker));
+ } else if (!strcmp(key, MAFW_PROPERTY_RENDERER_COLORKEY)) {
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_INT);
+ g_value_set_int(
+ value,
+ mafw_gst_renderer_worker_get_colorkey(
+ renderer->worker));
+ }
+#ifdef HAVE_GDKPIXBUF
+ else if (!strcmp(key,
+ MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE)) {
+ gboolean current_frame_on_pause;
+ current_frame_on_pause =
+ mafw_gst_renderer_worker_get_current_frame_on_pause(renderer->worker);
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_BOOLEAN);
+ g_value_set_boolean(value, current_frame_on_pause);
+ }
+#endif
+ else if (!strcmp(key,
+ MAFW_PROPERTY_GST_RENDERER_TV_CONNECTED)) {
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_BOOLEAN);
+ g_value_set_boolean(value, renderer->tv_connected);
+ }
+ else if (!strcmp(key,
+ MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS)){
+ /* Delegate in the state. */
+ value = mafw_gst_renderer_state_get_property_value(
+ MAFW_GST_RENDERER_STATE(
+ renderer->states[renderer->current_state]),
+ MAFW_PROPERTY_RENDERER_TRANSPORT_ACTIONS);
+
+ if (!value) {
+ /* Something goes wrong. */
+ error = g_error_new(
+ MAFW_GST_RENDERER_ERROR,
+ MAFW_EXTENSION_ERROR_GET_PROPERTY,
+ "Error while getting the property value");
+ }
+ }
+ else {
+ /* Unsupported property */
+ error = g_error_new(MAFW_GST_RENDERER_ERROR,
+ MAFW_EXTENSION_ERROR_GET_PROPERTY,
+ "Unsupported property");
+ }
+
+ callback(self, key, value, user_data, error);
+}
+
+static void mafw_gst_renderer_set_property(MafwExtension *self,
+ const gchar *key,
+ const GValue *value)
+{
+ MafwGstRenderer *renderer;
+
+ g_return_if_fail(MAFW_IS_GST_RENDERER(self));
+ g_return_if_fail(key != NULL);
+
+ renderer = MAFW_GST_RENDERER(self);
+
+ if (!strcmp(key, MAFW_PROPERTY_RENDERER_VOLUME)) {
+ guint volume = g_value_get_uint(value);
+ if (volume > 100)
+ volume = 100;
+ mafw_gst_renderer_worker_set_volume(renderer->worker,
+ volume);
+ /* Property-changed emision is done by worker */
+ return;
+ }
+ else if (!strcmp(key, MAFW_PROPERTY_RENDERER_MUTE)) {
+ gboolean mute = g_value_get_boolean(value);
+ mafw_gst_renderer_worker_set_mute(renderer->worker, mute);
+ }
+ else if (!strcmp(key, MAFW_PROPERTY_RENDERER_XID)) {
+ XID xid = g_value_get_uint(value);
+ mafw_gst_renderer_worker_set_xid(renderer->worker, xid);
+ }
+ else if (!strcmp(key, MAFW_PROPERTY_RENDERER_ERROR_POLICY)) {
+ MafwRendererErrorPolicy policy = g_value_get_uint(value);
+ _set_error_policy(renderer, policy);
+ }
+ else if (!strcmp(key, MAFW_PROPERTY_RENDERER_AUTOPAINT)) {
+ mafw_gst_renderer_worker_set_autopaint(
+ renderer->worker,
+ g_value_get_boolean(value));
+ }
+ else if (!strcmp(key, MAFW_PROPERTY_RENDERER_COLORKEY)) {
+ mafw_gst_renderer_worker_set_colorkey(
+ renderer->worker,
+ g_value_get_int(value));
+ }
+#ifdef HAVE_GDKPIXBUF
+ else if (!strcmp(key,
+ MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE)) {
+ gboolean current_frame_on_pause = g_value_get_boolean(value);
+ mafw_gst_renderer_worker_set_current_frame_on_pause(renderer->worker,
+ current_frame_on_pause);
+ }
+#endif
+ else return;
+
+ /* FIXME I'm not sure when to emit property-changed signals.
+ * Maybe we should let the worker do it, when the change
+ * reached the hardware... */
+ mafw_extension_emit_property_changed(self, key, value);
+}
+
+/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef MAFW_GST_RENDERER_H
+#define MAFW_GST_RENDERER_H
+
+#include <glib-object.h>
+#include <libmafw/mafw-renderer.h>
+#include <libmafw/mafw-registry.h>
+#include <gst/gst.h>
+#include <gst/pbutils/pbutils.h>
+#include <libhal.h>
+#include <gconf/gconf-client.h>
+
+#include "mafw-gst-renderer-utils.h"
+#include "mafw-gst-renderer-worker.h"
+#include "mafw-playlist-iterator.h"
+/* Solving the cyclic dependencies */
+typedef struct _MafwGstRenderer MafwGstRenderer;
+typedef struct _MafwGstRendererClass MafwGstRendererClass;
+#include "mafw-gst-renderer-state.h"
+
+#ifdef HAVE_CONIC
+#include <conicconnection.h>
+#endif
+
+typedef enum {
+ MAFW_GST_RENDERER_ERROR_PLUGIN_NOT_FOUND,
+ MAFW_GST_RENDERER_ERROR_VIDEO_CODEC_NOT_SUPPORTED,
+ MAFW_GST_RENDERER_ERROR_AUDIO_CODEC_NOT_SUPPORTED,
+} MafwGstRendererError;
+
+typedef enum {
+ MAFW_GST_RENDERER_MODE_PLAYLIST,
+ MAFW_GST_RENDERER_MODE_STANDALONE,
+} MafwGstRendererPlaybackMode;
+
+typedef enum {
+ MAFW_GST_RENDERER_MOVE_RESULT_OK,
+ MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST,
+ MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT,
+ MAFW_GST_RENDERER_MOVE_RESULT_ERROR,
+} MafwGstRendererMovementResult;
+
+typedef enum {
+ MAFW_GST_RENDERER_MOVE_TYPE_INDEX,
+ MAFW_GST_RENDERER_MOVE_TYPE_PREV,
+ MAFW_GST_RENDERER_MOVE_TYPE_NEXT,
+} MafwGstRendererMovementType;
+
+#ifdef HAVE_GDKPIXBUF
+#define MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE \
+ "current-frame-on-pause"
+#endif
+
+#define MAFW_PROPERTY_GST_RENDERER_TV_CONNECTED "tv-connected"
+
+/*----------------------------------------------------------------------------
+ GObject type conversion macros
+ ----------------------------------------------------------------------------*/
+
+#define MAFW_TYPE_GST_RENDERER \
+ (mafw_gst_renderer_get_type())
+#define MAFW_GST_RENDERER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_GST_RENDERER, MafwGstRenderer))
+#define MAFW_IS_GST_RENDERER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_GST_RENDERER))
+#define MAFW_GST_RENDERER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_GST_RENDERER, MafwGstRenderer))
+#define MAFW_GST_RENDERER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_GST_RENDERER, \
+ MafwGstRendererClass))
+#define MAFW_IS_GST_RENDERER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_GST_RENDERER))
+
+#define MAFW_GST_RENDERER_ERROR (mafw_gst_renderer_error_quark ())
+
+/* Gst renderer plugin name for the plugin descriptor */
+#define MAFW_GST_RENDERER_PLUGIN_NAME "Mafw-Gst-Renderer-Plugin"
+/* Gst renderer name */
+#define MAFW_GST_RENDERER_NAME "Mafw-Gst-Renderer"
+/* Gst renderer UUID */
+#define MAFW_GST_RENDERER_UUID "gstrenderer"
+
+/*----------------------------------------------------------------------------
+ Type definitions
+ ----------------------------------------------------------------------------*/
+
+typedef struct {
+ gchar *object_id;
+ gchar *uri;
+ gchar *title;
+ gchar *artist;
+ gchar *album;
+
+ gint duration;
+ gint position;
+
+ /* Seekability coming from source */
+ SeekabilityType seekability;
+} MafwGstRendererMedia;
+
+struct _MafwGstRendererClass {
+ MafwRendererClass parent;
+};
+
+/*
+ * media: Current media details
+ * worker: Worker
+ * registry: The registry that owns this renderer
+ * media_timer: Stream timer data
+ * current_state: The renderer's current state
+ * playlist: The renderer's playlist
+ * play_index: A playlist index that is currently playing
+ * seek_pending: Seek is pending or ongoing
+ * seek_type_pending: Type of the pending seek
+ * seeking_to: The position of pending seek (milliseconds)
+ * is_stream: is the URI a stream?
+ * play_failed_count: The number of unably played items from the playlist.
+ * playback_mode: Playback mode
+ * resume_playlist: Do we want to resume playlist playback when play_object
+ * is finished
+ * states: State array
+ * error_policy: error policy
+ * tv_connected: if TV-out cable is connected
+ */
+struct _MafwGstRenderer{
+ MafwRenderer parent;
+
+ MafwGstRendererMedia *media;
+ MafwGstRendererWorker *worker;
+ MafwRegistry *registry;
+ LibHalContext *hal_ctx;
+ MafwPlayState current_state;
+ MafwPlaylist *playlist;
+ MafwPlaylistIterator *iterator;
+ gboolean seek_pending;
+ GstSeekType seek_type_pending;
+ gint seeking_to;
+ gboolean is_stream;
+ gint update_playcount_id;
+ guint play_failed_count;
+
+ MafwGstRendererPlaybackMode playback_mode;
+ gboolean resume_playlist;
+ MafwGstRendererState **states;
+ MafwRendererErrorPolicy error_policy;
+ gboolean tv_connected;
+
+#ifdef HAVE_CONIC
+ gboolean connected;
+ ConIcConnection *connection;
+#endif
+ GConfClient *gconf_client;
+};
+
+typedef struct {
+ MafwGstRenderer *renderer;
+ GError *error;
+} MafwGstRendererErrorClosure;
+
+G_BEGIN_DECLS
+
+GType mafw_gst_renderer_get_type(void);
+GObject *mafw_gst_renderer_new(MafwRegistry *registry);
+GQuark mafw_gst_renderer_error_quark(void);
+
+/*----------------------------------------------------------------------------
+ Playback
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_play(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data);
+void mafw_gst_renderer_play_object(MafwRenderer *self, const gchar *object_id,
+ MafwRendererPlaybackCB callback,
+ gpointer user_data);
+void mafw_gst_renderer_stop(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data);
+void mafw_gst_renderer_pause(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data);
+void mafw_gst_renderer_resume(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data);
+
+/*----------------------------------------------------------------------------
+ Status
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_get_status(MafwRenderer *self, MafwRendererStatusCB callback,
+ gpointer user_data);
+
+/*----------------------------------------------------------------------------
+ Set Media
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_set_object(MafwGstRenderer *self, const gchar *object_id);
+void mafw_gst_renderer_clear_media(MafwGstRenderer *self);
+
+/*----------------------------------------------------------------------------
+ Metadata
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_get_metadata(MafwGstRenderer* self, const gchar* objectid,
+ GError **error);
+gboolean mafw_gst_renderer_update_stats(gpointer data);
+
+/*----------------------------------------------------------------------------
+ Playlist
+ ----------------------------------------------------------------------------*/
+
+gboolean mafw_gst_renderer_assign_playlist(MafwRenderer *self,
+ MafwPlaylist *playlist,
+ GError **error);
+void mafw_gst_renderer_next(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data);
+void mafw_gst_renderer_previous(MafwRenderer *self, MafwRendererPlaybackCB callback,
+ gpointer user_data);
+void mafw_gst_renderer_goto_index(MafwRenderer *self, guint index,
+ MafwRendererPlaybackCB callback,
+ gpointer user_data);
+MafwGstRendererMovementResult mafw_gst_renderer_move(MafwGstRenderer *renderer,
+ MafwGstRendererMovementType type,
+ guint index,
+ GError **error);
+
+/*----------------------------------------------------------------------------
+ Set media
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_set_media_playlist(MafwGstRenderer* self);
+
+/*----------------------------------------------------------------------------
+ Position
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_set_position(MafwRenderer *self,
+ MafwRendererSeekMode mode, gint seconds,
+ MafwRendererPositionCB callback,
+ gpointer user_data);
+void mafw_gst_renderer_get_position(MafwRenderer *self, MafwRendererPositionCB callback,
+ gpointer user_data);
+
+/*----------------------------------------------------------------------------
+ Metadata
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_get_current_metadata(MafwRenderer *self,
+ MafwRendererMetadataResultCB callback,
+ gpointer user_data);
+
+/*----------------------------------------------------------------------------
+ Local API
+ ----------------------------------------------------------------------------*/
+
+void mafw_gst_renderer_set_state(MafwGstRenderer *self, MafwPlayState state);
+
+gboolean mafw_gst_renderer_manage_error_idle(gpointer data);
+
+void mafw_gst_renderer_manage_error(MafwGstRenderer *self, const GError *error);
+
+void mafw_gst_renderer_set_playback_mode(MafwGstRenderer *self,
+ MafwGstRendererPlaybackMode mode);
+
+MafwGstRendererPlaybackMode mafw_gst_renderer_get_playback_mode(
+ MafwGstRenderer *self);
+
+void mafw_gst_renderer_update_source_duration(MafwGstRenderer *renderer,
+ gint duration);
+
+G_END_DECLS
+
+#endif
+
+/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "mafw-playlist-iterator.h"
+#include "mafw-gst-renderer-marshal.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-playlist-iterator"
+
+struct _MafwPlaylistIteratorPrivate {
+ MafwPlaylist *playlist;
+ gint current_index;
+ gchar *current_objectid;
+ gint size;
+};
+
+typedef gboolean (*movement_function) (MafwPlaylist *playlist,
+ guint *index,
+ gchar **objectid,
+ GError **error);
+
+enum {
+ PLAYLIST_CHANGED = 0,
+ LAST_SIGNAL,
+};
+
+static guint mafw_playlist_iterator_signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE(MafwPlaylistIterator, mafw_playlist_iterator, G_TYPE_OBJECT);
+
+static void
+mafw_playlist_iterator_dispose(GObject *object)
+{
+ MafwPlaylistIterator *iterator = (MafwPlaylistIterator *) object;
+
+ g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
+
+ mafw_playlist_iterator_invalidate(iterator);
+
+ G_OBJECT_CLASS(mafw_playlist_iterator_parent_class)->dispose(object);
+}
+
+static void
+mafw_playlist_iterator_class_init(MafwPlaylistIteratorClass *klass)
+{
+ GObjectClass *gclass = NULL;
+
+ gclass = G_OBJECT_CLASS(klass);
+ g_return_if_fail(gclass != NULL);
+
+ g_type_class_add_private(klass, sizeof(MafwPlaylistIteratorPrivate));
+
+ gclass->dispose = mafw_playlist_iterator_dispose;
+
+ mafw_playlist_iterator_signals[PLAYLIST_CHANGED] =
+ g_signal_new("playlist-changed",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(MafwPlaylistIteratorClass, playlist_changed),
+ NULL,
+ NULL,
+ mafw_gst_renderer_marshal_VOID__BOOLEAN_UINT_INT_STRING,
+ G_TYPE_NONE,
+ 4,
+ G_TYPE_BOOLEAN,
+ G_TYPE_UINT, G_TYPE_INT, G_TYPE_STRING);
+}
+
+static void
+mafw_playlist_iterator_init(MafwPlaylistIterator *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
+ MAFW_TYPE_PLAYLIST_ITERATOR,
+ MafwPlaylistIteratorPrivate);
+}
+
+static void
+mafw_playlist_iterator_set_data(MafwPlaylistIterator *iterator, gint index,
+ gchar *objectid)
+{
+ g_assert(mafw_playlist_iterator_is_valid(iterator));
+
+ g_free(iterator->priv->current_objectid);
+ iterator->priv->current_index = index;
+ iterator->priv->current_objectid = objectid;
+}
+
+static MafwPlaylistIteratorMovementResult
+mafw_playlist_iterator_move_to_next_in_direction(MafwPlaylistIterator *iterator,
+ movement_function get_next_in_direction,
+ GError **error)
+{
+ gint index;
+ gchar *objectid = NULL;
+ GError *new_error = NULL;
+ gboolean playlist_movement_result = FALSE;
+ MafwPlaylistIteratorMovementResult iterator_movement_result =
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK;
+
+ g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator),
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_INVALID);
+
+ index = iterator->priv->current_index;
+
+ playlist_movement_result =
+ get_next_in_direction (iterator->priv->playlist,
+ (guint *) &index,
+ &objectid, &new_error);
+
+ if (new_error != NULL) {
+ g_propagate_error(error, new_error);
+ iterator_movement_result =
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR;
+ } else if (playlist_movement_result) {
+ mafw_playlist_iterator_set_data(iterator, index, objectid);
+ } else {
+ iterator_movement_result =
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_LIMIT;
+ }
+
+ return iterator_movement_result;
+}
+
+static void
+mafw_playlist_iterator_playlist_contents_changed_handler(MafwPlaylist *playlist,
+ guint from,
+ guint nremove,
+ guint nreplace,
+ gpointer user_data)
+{
+ gint play_index;
+ gboolean clip_changed = FALSE;
+ GError *error = NULL;
+ MafwPlaylistIterator *iterator = (MafwPlaylistIterator*) user_data;
+
+ g_return_if_fail(MAFW_IS_PLAYLIST(playlist));
+ g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
+
+ if (iterator->priv->playlist == NULL) {
+ g_critical("Got playlist:contents-changed but renderer has no" \
+ "playlist assigned!. Skipping...");
+ return;
+ }
+
+ play_index = iterator->priv->current_index;
+ iterator->priv->size += nreplace;
+
+ if (nremove > 0) {
+ /* Items have been removed from the playlist */
+ iterator->priv->size -= nremove;
+ if ((play_index >= from) &&
+ (play_index < from + nremove)) {
+ /* The current index has been removed */
+ guint pls_size =
+ mafw_playlist_iterator_get_size(iterator,
+ &error);
+ if (error == NULL) {
+ /* Is the current index invalid now? If not,
+ set current item to the last in the playlist,
+ otherwise the keep the index and update the
+ media */
+ if (pls_size == 0) {
+ mafw_playlist_iterator_set_data(iterator, -1, NULL);
+ } else if (play_index >= pls_size) {
+ mafw_playlist_iterator_move_to_index(iterator,
+ pls_size - 1,
+ &error);
+ } else {
+ mafw_playlist_iterator_update(iterator,
+ &error);
+ }
+
+ clip_changed = TRUE;
+ }
+ } else if (from < play_index) {
+ /* The current index has been moved towards
+ the head of the playlist */
+ play_index -= nremove;
+ if (play_index < 0) {
+ play_index = 0;
+ }
+ mafw_playlist_iterator_move_to_index(iterator,
+ play_index,
+ &error);
+ }
+ } else if (nremove == 0) {
+ /* Items have been inserted in the playlist */
+ if (play_index == -1) {
+ /* First item has been added to an empty playlist */
+ mafw_playlist_iterator_reset(iterator,
+ &error);
+ clip_changed = TRUE;
+ } else if (play_index >= from) {
+ /* The current item has been moved towards the
+ tail of the playlist */
+ mafw_playlist_iterator_move_to_index(iterator,
+ play_index + nreplace,
+ &error);
+ }
+ }
+
+ if (error != NULL) {
+ g_critical("playlist::contents-changed handler failed "
+ "with \"%s\"", error->message);
+ g_signal_emit(iterator,
+ mafw_playlist_iterator_signals[PLAYLIST_CHANGED],
+ 0, FALSE, error->domain, error->code, error->message);
+ g_error_free (error);
+ } else {
+ g_signal_emit(iterator,
+ mafw_playlist_iterator_signals[PLAYLIST_CHANGED],
+ 0, clip_changed, 0, 0, NULL);
+ }
+}
+
+static void
+mafw_playlist_iterator_playlist_item_moved_handler(MafwPlaylist *playlist,
+ guint from,
+ guint to,
+ gpointer user_data)
+{
+ MafwPlaylistIterator *iterator = (MafwPlaylistIterator *) user_data;
+ gint play_index;
+ GError *error = NULL;
+
+ g_return_if_fail(MAFW_IS_PLAYLIST(playlist));
+ g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
+
+ if (iterator->priv->playlist == NULL) {
+ g_critical("Got playlist:item-moved but renderer has not a " \
+ "playlist assigned! Skipping...");
+ return;
+ }
+
+ play_index = iterator->priv->current_index;
+
+ if (play_index == from) {
+ /* So the current item has been moved, let's update the
+ the current index to the new location */
+ mafw_playlist_iterator_move_to_index(iterator, to, &error);
+ } else if (play_index > from && play_index <= to) {
+ /* So we current item has been pushed one position towards
+ the head, let's update the current index */
+ mafw_playlist_iterator_move_to_prev(iterator, &error);
+ } else if (play_index >= to && play_index < from) {
+ /* So we current item has been pushed one position towards
+ the head, let's update the current index */
+ mafw_playlist_iterator_move_to_next(iterator, &error);
+ }
+
+ if (error != NULL) {
+ g_critical("playlist::item-moved handler failed "
+ "with \"%s\"", error->message);
+ g_error_free (error);
+ }
+}
+
+MafwPlaylistIterator *
+mafw_playlist_iterator_new(void)
+{
+ MafwPlaylistIterator *iterator = (MafwPlaylistIterator *)
+ g_object_new(MAFW_TYPE_PLAYLIST_ITERATOR, NULL);
+
+ g_assert(iterator != NULL);
+
+ iterator->priv->playlist = NULL;
+ iterator->priv->current_index = -1;
+ iterator->priv->current_objectid = NULL;
+ iterator->priv->size = -1;
+
+ return iterator;
+}
+
+void
+mafw_playlist_iterator_initialize(MafwPlaylistIterator *iterator,
+ MafwPlaylist *playlist, GError **error)
+{
+ guint size;
+ gint index = -1;
+ gchar *objectid = NULL;
+ GError *new_error = NULL;
+
+ g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
+ g_return_if_fail(iterator->priv->playlist == NULL);
+
+ iterator->priv->size = -1;
+
+ mafw_playlist_get_starting_index(playlist, (guint *) &index, &objectid,
+ &new_error);
+
+ if (new_error == NULL) {
+ size = mafw_playlist_get_size(playlist, &new_error);
+ }
+
+ if (new_error == NULL) {
+ iterator->priv->playlist = g_object_ref(playlist);
+ iterator->priv->current_index = index;
+ iterator->priv->current_objectid = objectid;
+ iterator->priv->size = size;
+
+ g_signal_connect(playlist,
+ "item-moved",
+ G_CALLBACK(mafw_playlist_iterator_playlist_item_moved_handler),
+ iterator);
+ g_signal_connect(playlist,
+ "contents-changed",
+ G_CALLBACK(mafw_playlist_iterator_playlist_contents_changed_handler),
+ iterator);
+ }
+ else {
+ g_propagate_error (error, new_error);
+ }
+}
+
+void
+mafw_playlist_iterator_invalidate(MafwPlaylistIterator *iterator)
+{
+ g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
+
+ if (iterator->priv->playlist != NULL) {
+ g_signal_handlers_disconnect_matched(iterator->priv->playlist,
+ (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ mafw_playlist_iterator_playlist_item_moved_handler,
+ NULL);
+
+ g_signal_handlers_disconnect_matched(iterator->priv->playlist,
+ (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ mafw_playlist_iterator_playlist_contents_changed_handler,
+ NULL);
+
+ g_object_unref(iterator->priv->playlist);
+ g_free(iterator->priv->current_objectid);
+ iterator->priv->playlist = NULL;
+ iterator->priv->current_index = -1;
+ iterator->priv->current_objectid = NULL;
+ iterator->priv->size = -1;
+ }
+}
+
+gboolean
+mafw_playlist_iterator_is_valid(MafwPlaylistIterator *iterator)
+{
+ g_return_val_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator), FALSE);
+
+ return iterator->priv->playlist != NULL;
+}
+
+void
+mafw_playlist_iterator_reset(MafwPlaylistIterator *iterator, GError **error)
+{
+ gint index = -1;
+ gchar *objectid = NULL;
+ GError *new_error = NULL;
+
+ g_return_if_fail(mafw_playlist_iterator_is_valid(iterator));
+
+ mafw_playlist_get_starting_index(iterator->priv->playlist,
+ (guint *) &index,
+ &objectid, &new_error);
+
+ if (new_error == NULL) {
+ mafw_playlist_iterator_set_data(iterator, index, objectid);
+ }
+ else {
+ g_propagate_error (error, new_error);
+ }
+}
+
+void
+mafw_playlist_iterator_move_to_last(MafwPlaylistIterator *iterator,
+ GError **error)
+{
+ GError *new_error = NULL;
+ gint index = -1;
+ gchar *objectid = NULL;
+
+ g_return_if_fail(mafw_playlist_iterator_is_valid(iterator));
+
+ mafw_playlist_get_last_index(iterator->priv->playlist,
+ (guint *) &index,
+ &objectid, &new_error);
+
+ if (new_error == NULL) {
+ mafw_playlist_iterator_set_data(iterator, index, objectid);
+ }
+ else {
+ g_propagate_error (error, new_error);
+ }
+}
+
+MafwPlaylistIteratorMovementResult
+mafw_playlist_iterator_move_to_next(MafwPlaylistIterator *iterator,
+ GError **error)
+{
+ return mafw_playlist_iterator_move_to_next_in_direction(iterator,
+ mafw_playlist_get_next,
+ error);
+}
+
+MafwPlaylistIteratorMovementResult
+mafw_playlist_iterator_move_to_prev(MafwPlaylistIterator *iterator,
+ GError **error)
+{
+ return mafw_playlist_iterator_move_to_next_in_direction(iterator,
+ mafw_playlist_get_prev,
+ error);
+}
+
+MafwPlaylistIteratorMovementResult
+mafw_playlist_iterator_move_to_index(MafwPlaylistIterator *iterator,
+ gint index,
+ GError **error)
+{
+ GError *new_error = NULL;
+ MafwPlaylistIteratorMovementResult iterator_movement_result =
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK;
+ gint playlist_size;
+
+ g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator),
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_INVALID);
+
+ playlist_size = mafw_playlist_iterator_get_size(iterator, &new_error);
+
+ if (new_error != NULL) {
+ g_propagate_error(error, new_error);
+ iterator_movement_result =
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR;
+ } else if ((index < 0) || (index >= playlist_size)) {
+ iterator_movement_result =
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_LIMIT;
+ } else {
+ gchar *objectid =
+ mafw_playlist_get_item(iterator->priv->playlist,
+ index,
+ &new_error);
+
+ if (new_error != NULL) {
+ g_propagate_error(error, new_error);
+ iterator_movement_result =
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR;
+ } else {
+ mafw_playlist_iterator_set_data(iterator, index, objectid);
+ }
+ }
+
+ return iterator_movement_result;
+}
+
+void
+mafw_playlist_iterator_update(MafwPlaylistIterator *iterator, GError **error)
+{
+ GError *new_error = NULL;
+ gchar *objectid = NULL;
+
+ objectid =
+ mafw_playlist_get_item(iterator->priv->playlist,
+ iterator->priv->current_index,
+ &new_error);
+
+ if (new_error != NULL) {
+ g_propagate_error(error, new_error);
+ } else {
+ mafw_playlist_iterator_set_data(iterator,
+ iterator->priv->current_index,
+ objectid);
+ }
+}
+
+const gchar *
+mafw_playlist_iterator_get_current_objectid(MafwPlaylistIterator *iterator)
+{
+ g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator), NULL);
+
+ return iterator->priv->current_objectid;
+}
+
+gint
+mafw_playlist_iterator_get_current_index(MafwPlaylistIterator *iterator)
+{
+ g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator), 0);
+
+ return iterator->priv->current_index;
+}
+
+gint
+mafw_playlist_iterator_get_size(MafwPlaylistIterator *iterator,
+ GError **error)
+{
+ g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator), -1);
+
+ if (iterator->priv->size == -1) {
+ iterator->priv->size =
+ mafw_playlist_get_size(iterator->priv->playlist,
+ error);
+ }
+
+ return iterator->priv->size;
+}
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef MAFW_PLAYLIST_ITERATOR_H
+#define MAFW_PLAYLIST_ITERATOR_H
+
+#include <glib-object.h>
+#include <libmafw/mafw.h>
+
+G_BEGIN_DECLS
+
+typedef struct _MafwPlaylistIteratorPrivate MafwPlaylistIteratorPrivate;
+
+typedef struct {
+ GObject g_object;
+
+ MafwPlaylistIteratorPrivate *priv;
+} MafwPlaylistIterator;
+
+typedef struct {
+ GObjectClass g_object_class;
+
+ /* Signals */
+ void (*playlist_changed)(MafwPlaylistIterator *iterator,
+ gboolean current_item_changed,
+ GQuark domain, gint code, const gchar *message);
+} MafwPlaylistIteratorClass;
+
+typedef enum {
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK,
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_LIMIT,
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_INVALID,
+ MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR,
+} MafwPlaylistIteratorMovementResult;
+
+#define MAFW_TYPE_PLAYLIST_ITERATOR \
+ (mafw_playlist_iterator_get_type())
+#define MAFW_PLAYLIST_ITERATOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), MAFW_TYPE_PLAYLIST_ITERATOR, MafwPlaylistIterator))
+#define MAFW_IS_PLAYLIST_ITERATOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAFW_TYPE_PLAYLIST_ITERATOR))
+#define MAFW_PLAYLIST_ITERATOR_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), MAFW_TYPE_PLAYLIST_ITERATOR, MafwPlaylistIterator))
+#define MAFW_PLAYLIST_ITERATOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_PLAYLIST_ITERATOR, \
+ MafwPlaylistIteratorClass))
+#define MAFW_IS_PLAYLIST_ITERATOR_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_PLAYLIST_ITERATOR))
+
+G_END_DECLS
+
+GType mafw_playlist_iterator_get_type(void);
+MafwPlaylistIterator *mafw_playlist_iterator_new(void);
+void mafw_playlist_iterator_initialize(MafwPlaylistIterator *iterator,
+ MafwPlaylist *playlist,
+ GError **error);
+void mafw_playlist_iterator_invalidate(MafwPlaylistIterator *iterator);
+gboolean mafw_playlist_iterator_is_valid(MafwPlaylistIterator *iterator);
+void mafw_playlist_iterator_reset(MafwPlaylistIterator *iterator, GError **error);
+void mafw_playlist_iterator_move_to_last(MafwPlaylistIterator *iterator, GError **error);
+MafwPlaylistIteratorMovementResult mafw_playlist_iterator_move_to_next(MafwPlaylistIterator *iterator,
+ GError **error);
+MafwPlaylistIteratorMovementResult mafw_playlist_iterator_move_to_prev(MafwPlaylistIterator *iterator,
+ GError **error);
+MafwPlaylistIteratorMovementResult mafw_playlist_iterator_move_to_index(MafwPlaylistIterator *iterator,
+ gint index,
+ GError **error);
+void mafw_playlist_iterator_update(MafwPlaylistIterator *iterator, GError **error);
+const gchar *mafw_playlist_iterator_get_current_objectid(MafwPlaylistIterator *iterator);
+gint mafw_playlist_iterator_get_current_index(MafwPlaylistIterator *iterator);
+gint mafw_playlist_iterator_get_size(MafwPlaylistIterator *iterator,
+ GError **error);
+
+#endif
--- /dev/null
+prefix=
+exec_prefix=
+libdir=${pcfiledir}/libmafw-gst-renderer
+includedir=${pcfiledir}/
+
+Name: mafw-gst-renderer
+Description: MAFW local renderer
+Version: @VERSION@
+Libs: ${libdir}/mafw-gst-renderer.la
+Cflags: -I${includedir}
+Requires: gobject-2.0 gstreamer-0.10 mafw
--- /dev/null
+# Please keep this list sorted alphabetically
+#
+cs
+da
+de
+fi
+hu
+sk
--- /dev/null
+# List of source files containing translatable strings.
+
+applet/cpmpsubtitles.c
+applet/cpmpsubtitles.desktop
--- /dev/null
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Roman Moravčík <roman.moravcik@gmail.com>, 2010.
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: mafw-gst-subtitles-renderer\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-18 15:46+0100\n"
+"PO-Revision-Date: 2010-01-19 09:56+0100\n"
+"Last-Translator: Roman Moravčík <roman.moravcik@gmail.com>\n"
+"Language-Team: Czech <>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../applet/cpmpsubtitles.c:59
+msgid "Regular"
+msgstr ""
+
+#: ../applet/cpmpsubtitles.c:60
+msgid "Italic"
+msgstr "Kurzíva"
+
+#: ../applet/cpmpsubtitles.c:61
+msgid "Bold"
+msgstr "Tučné"
+
+#: ../applet/cpmpsubtitles.c:62
+msgid "Italic Bold"
+msgstr "Tučné kurzíva"
+
+#: ../applet/cpmpsubtitles.c:187
+msgid "Current Locale"
+msgstr "Aktuální lokalizace"
+
+#: ../applet/cpmpsubtitles.c:189 ../applet/cpmpsubtitles.c:190
+#: ../applet/cpmpsubtitles.c:191 ../applet/cpmpsubtitles.c:192
+msgid "Arabic"
+msgstr "Arabské"
+
+#: ../applet/cpmpsubtitles.c:194
+msgid "Armenian"
+msgstr "Arménské"
+
+#: ../applet/cpmpsubtitles.c:196 ../applet/cpmpsubtitles.c:197
+#: ../applet/cpmpsubtitles.c:198
+msgid "Baltic"
+msgstr "Baltské"
+
+#: ../applet/cpmpsubtitles.c:200
+msgid "Celtic"
+msgstr "Keltské"
+
+#: ../applet/cpmpsubtitles.c:202 ../applet/cpmpsubtitles.c:203
+#: ../applet/cpmpsubtitles.c:204 ../applet/cpmpsubtitles.c:205
+msgid "Central European"
+msgstr "Střední Evropa"
+
+#: ../applet/cpmpsubtitles.c:207 ../applet/cpmpsubtitles.c:208
+#: ../applet/cpmpsubtitles.c:209 ../applet/cpmpsubtitles.c:210
+msgid "Chinese Simplified"
+msgstr "Zjednodušené čínské"
+
+#: ../applet/cpmpsubtitles.c:212 ../applet/cpmpsubtitles.c:213
+#: ../applet/cpmpsubtitles.c:214
+msgid "Chinese Traditional"
+msgstr "Tradiční čínské"
+
+#: ../applet/cpmpsubtitles.c:216
+msgid "Croatian"
+msgstr "Chorvatské"
+
+#: ../applet/cpmpsubtitles.c:218 ../applet/cpmpsubtitles.c:219
+#: ../applet/cpmpsubtitles.c:220 ../applet/cpmpsubtitles.c:221
+#: ../applet/cpmpsubtitles.c:222 ../applet/cpmpsubtitles.c:223
+msgid "Cyrillic"
+msgstr "Cyrilice"
+
+#: ../applet/cpmpsubtitles.c:225
+msgid "Cyrillic/Russian"
+msgstr "Cyrilice/ruské"
+
+#: ../applet/cpmpsubtitles.c:227 ../applet/cpmpsubtitles.c:228
+msgid "Cyrillic/Ukrainian"
+msgstr "Cyrilice/ukrajinské"
+
+#: ../applet/cpmpsubtitles.c:230
+msgid "Georgian"
+msgstr "Gruzínské"
+
+#: ../applet/cpmpsubtitles.c:232 ../applet/cpmpsubtitles.c:233
+#: ../applet/cpmpsubtitles.c:234
+msgid "Greek"
+msgstr "Řecké"
+
+#: ../applet/cpmpsubtitles.c:236
+msgid "Gujarati"
+msgstr "Gudžarátské"
+
+#: ../applet/cpmpsubtitles.c:238
+msgid "Gurmukhi"
+msgstr "Gurmuchské"
+
+#: ../applet/cpmpsubtitles.c:240 ../applet/cpmpsubtitles.c:241
+#: ../applet/cpmpsubtitles.c:242 ../applet/cpmpsubtitles.c:243
+msgid "Hebrew"
+msgstr "Hebrejské"
+
+#: ../applet/cpmpsubtitles.c:245
+msgid "Hebrew Visual"
+msgstr "Hebrejské vizuální"
+
+#: ../applet/cpmpsubtitles.c:247
+msgid "Hindi"
+msgstr "Hindské"
+
+#: ../applet/cpmpsubtitles.c:249
+msgid "Icelandic"
+msgstr "Islandské"
+
+#: ../applet/cpmpsubtitles.c:251 ../applet/cpmpsubtitles.c:252
+#: ../applet/cpmpsubtitles.c:253
+msgid "Japanese"
+msgstr "Japonské"
+
+#: ../applet/cpmpsubtitles.c:255 ../applet/cpmpsubtitles.c:256
+#: ../applet/cpmpsubtitles.c:257 ../applet/cpmpsubtitles.c:258
+msgid "Korean"
+msgstr "Korejské"
+
+#: ../applet/cpmpsubtitles.c:260
+msgid "Nordic"
+msgstr "Nordické"
+
+#: ../applet/cpmpsubtitles.c:262
+msgid "Persian"
+msgstr "Perské"
+
+#: ../applet/cpmpsubtitles.c:264 ../applet/cpmpsubtitles.c:265
+msgid "Romanian"
+msgstr "Rumunské"
+
+#: ../applet/cpmpsubtitles.c:267
+msgid "South European"
+msgstr "Jihoevropské"
+
+#: ../applet/cpmpsubtitles.c:269
+msgid "Thai"
+msgstr "Thajské"
+
+#: ../applet/cpmpsubtitles.c:271 ../applet/cpmpsubtitles.c:272
+#: ../applet/cpmpsubtitles.c:273 ../applet/cpmpsubtitles.c:274
+msgid "Turkish"
+msgstr "Turecké"
+
+#: ../applet/cpmpsubtitles.c:276 ../applet/cpmpsubtitles.c:277
+#: ../applet/cpmpsubtitles.c:278 ../applet/cpmpsubtitles.c:279
+#: ../applet/cpmpsubtitles.c:280
+msgid "Unicode"
+msgstr "Unicode"
+
+#: ../applet/cpmpsubtitles.c:282 ../applet/cpmpsubtitles.c:283
+#: ../applet/cpmpsubtitles.c:284 ../applet/cpmpsubtitles.c:285
+#: ../applet/cpmpsubtitles.c:286
+msgid "Western"
+msgstr "Západní"
+
+#: ../applet/cpmpsubtitles.c:288 ../applet/cpmpsubtitles.c:289
+#: ../applet/cpmpsubtitles.c:290
+msgid "Vietnamese"
+msgstr "Vietnamské"
+
+#: ../applet/cpmpsubtitles.c:427 ../applet/cpmpsubtitles.c:622
+msgid "Font"
+msgstr "Písmo"
+
+#: ../applet/cpmpsubtitles.c:593
+msgid "Automatically load subtitle files"
+msgstr "Automaticky nahrát titulky"
+
+#: ../applet/cpmpsubtitles.c:659
+msgid "Encoding"
+msgstr "Kódování"
+
+#: ../applet/cpmpsubtitles.c:724
+msgid "Subtitles"
+msgstr "Titulky"
--- /dev/null
+# Danish translation of MAFW.
+# Copyright (C) 2010 MAFW & Joe Hansen.
+# This file is distributed under the same license as the MAFW package.
+# Joe Hansen <joedalton2@yahoo.dk>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Development\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-02-01 04:03+0000\n"
+"PO-Revision-Date: 2010-02-01 17:30+01:00\n"
+"Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
+"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../applet/cpmpsubtitles.c:59
+msgid "Regular"
+msgstr "Normal"
+
+#: ../applet/cpmpsubtitles.c:60
+msgid "Italic"
+msgstr "Kursiv"
+
+#: ../applet/cpmpsubtitles.c:61
+msgid "Bold"
+msgstr "Fed"
+
+#: ../applet/cpmpsubtitles.c:62
+msgid "Italic Bold"
+msgstr "Kursiv og fed"
+
+#: ../applet/cpmpsubtitles.c:187 ../applet/cpmpsubtitles.c:188
+#: ../applet/cpmpsubtitles.c:189 ../applet/cpmpsubtitles.c:190
+msgid "Arabic"
+msgstr "Arabisk"
+
+#: ../applet/cpmpsubtitles.c:192
+msgid "Armenian"
+msgstr "Armensk"
+
+#: ../applet/cpmpsubtitles.c:194 ../applet/cpmpsubtitles.c:195
+#: ../applet/cpmpsubtitles.c:196
+msgid "Baltic"
+msgstr "Baltisk"
+
+#: ../applet/cpmpsubtitles.c:198
+msgid "Celtic"
+msgstr "Keltisk"
+
+#: ../applet/cpmpsubtitles.c:200 ../applet/cpmpsubtitles.c:201
+#: ../applet/cpmpsubtitles.c:202 ../applet/cpmpsubtitles.c:203
+msgid "Central European"
+msgstr "Centraleuropæisk"
+
+#: ../applet/cpmpsubtitles.c:205 ../applet/cpmpsubtitles.c:206
+#: ../applet/cpmpsubtitles.c:207 ../applet/cpmpsubtitles.c:208
+msgid "Chinese Simplified"
+msgstr "Forenklet kinesisk"
+
+#: ../applet/cpmpsubtitles.c:210 ../applet/cpmpsubtitles.c:211
+#: ../applet/cpmpsubtitles.c:212
+msgid "Chinese Traditional"
+msgstr "Traditionel kinesisk"
+
+#: ../applet/cpmpsubtitles.c:214
+msgid "Croatian"
+msgstr "Kroatisk"
+
+#: ../applet/cpmpsubtitles.c:216 ../applet/cpmpsubtitles.c:217
+#: ../applet/cpmpsubtitles.c:218 ../applet/cpmpsubtitles.c:219
+#: ../applet/cpmpsubtitles.c:220 ../applet/cpmpsubtitles.c:221
+msgid "Cyrillic"
+msgstr "Kyrillisk"
+
+#: ../applet/cpmpsubtitles.c:223
+msgid "Cyrillic/Russian"
+msgstr "Kyrillisk/russisk"
+
+#: ../applet/cpmpsubtitles.c:225 ../applet/cpmpsubtitles.c:226
+msgid "Cyrillic/Ukrainian"
+msgstr "Kyrillisk/ukrainsk"
+
+#: ../applet/cpmpsubtitles.c:228
+msgid "Georgian"
+msgstr "Georgisk"
+
+#: ../applet/cpmpsubtitles.c:230 ../applet/cpmpsubtitles.c:231
+#: ../applet/cpmpsubtitles.c:232
+msgid "Greek"
+msgstr "Græsk"
+
+#: ../applet/cpmpsubtitles.c:234
+msgid "Gujarati"
+msgstr "Gujarati"
+
+#: ../applet/cpmpsubtitles.c:236
+msgid "Gurmukhi"
+msgstr "Gurmukhi"
+
+#: ../applet/cpmpsubtitles.c:238 ../applet/cpmpsubtitles.c:239
+#: ../applet/cpmpsubtitles.c:240 ../applet/cpmpsubtitles.c:241
+msgid "Hebrew"
+msgstr "Hebraisk"
+
+#: ../applet/cpmpsubtitles.c:243
+msgid "Hebrew Visual"
+msgstr "Visuelt hebraisk"
+
+#: ../applet/cpmpsubtitles.c:245
+msgid "Hindi"
+msgstr "Hindi"
+
+#: ../applet/cpmpsubtitles.c:247
+msgid "Icelandic"
+msgstr "Islandsk"
+
+#: ../applet/cpmpsubtitles.c:249 ../applet/cpmpsubtitles.c:250
+#: ../applet/cpmpsubtitles.c:251
+msgid "Japanese"
+msgstr "Japansk"
+
+#: ../applet/cpmpsubtitles.c:253 ../applet/cpmpsubtitles.c:254
+#: ../applet/cpmpsubtitles.c:255 ../applet/cpmpsubtitles.c:256
+msgid "Korean"
+msgstr "Koreansk"
+
+#: ../applet/cpmpsubtitles.c:258
+msgid "Nordic"
+msgstr "Nordisk"
+
+#: ../applet/cpmpsubtitles.c:260
+msgid "Persian"
+msgstr "Iransk"
+
+#: ../applet/cpmpsubtitles.c:262 ../applet/cpmpsubtitles.c:263
+msgid "Romanian"
+msgstr "Rumænsk"
+
+#: ../applet/cpmpsubtitles.c:265
+msgid "South European"
+msgstr "Sydeuropæisk"
+
+#: ../applet/cpmpsubtitles.c:267
+msgid "Thai"
+msgstr "Thai"
+
+#: ../applet/cpmpsubtitles.c:269 ../applet/cpmpsubtitles.c:270
+#: ../applet/cpmpsubtitles.c:271 ../applet/cpmpsubtitles.c:272
+msgid "Turkish"
+msgstr "Tyrkisk"
+
+#: ../applet/cpmpsubtitles.c:274 ../applet/cpmpsubtitles.c:275
+#: ../applet/cpmpsubtitles.c:276 ../applet/cpmpsubtitles.c:277
+#: ../applet/cpmpsubtitles.c:278
+msgid "Unicode"
+msgstr "Unicode"
+
+#: ../applet/cpmpsubtitles.c:280 ../applet/cpmpsubtitles.c:281
+#: ../applet/cpmpsubtitles.c:282 ../applet/cpmpsubtitles.c:283
+#: ../applet/cpmpsubtitles.c:284
+msgid "Western"
+msgstr "Vestligt"
+
+#: ../applet/cpmpsubtitles.c:286 ../applet/cpmpsubtitles.c:287
+#: ../applet/cpmpsubtitles.c:288
+msgid "Vietnamese"
+msgstr "Vietnamesisk"
+
+#: ../applet/cpmpsubtitles.c:290
+msgid "Current Locale"
+msgstr "Nuværende sprog"
+
+#: ../applet/cpmpsubtitles.c:432 ../applet/cpmpsubtitles.c:631
+msgid "Font"
+msgstr "Skrifttype"
+
+#: ../applet/cpmpsubtitles.c:602
+msgid "Automatically load subtitle files"
+msgstr "Indlæs automatisk undertekstfiler"
+
+# Det skal vel ikke være kodning her, men sprog?
+#: ../applet/cpmpsubtitles.c:668
+msgid "Encoding"
+msgstr "Sprog"
+
+#: ../applet/cpmpsubtitles.c:733
+msgid "Subtitles"
+msgstr "Undertekster"
--- /dev/null
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: mafw-gst-subtitles-render\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-20 14:17+0000\n"
+"PO-Revision-Date: 2010-01-20 19:01+0100\n"
+"Last-Translator: Philipp Zabel <philipp.zabel@gmail.com>\n"
+"Language-Team: German\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+
+#: ../applet/cpmpsubtitles.c:59
+msgid "Regular"
+msgstr "Normal"
+
+#: ../applet/cpmpsubtitles.c:60
+msgid "Italic"
+msgstr "Kursiv"
+
+#: ../applet/cpmpsubtitles.c:61
+msgid "Bold"
+msgstr "Fett"
+
+#: ../applet/cpmpsubtitles.c:62
+msgid "Italic Bold"
+msgstr "Fett Kursiv"
+
+#: ../applet/cpmpsubtitles.c:187
+#: ../applet/cpmpsubtitles.c:188
+#: ../applet/cpmpsubtitles.c:189
+#: ../applet/cpmpsubtitles.c:190
+msgid "Arabic"
+msgstr "Arabisch"
+
+#: ../applet/cpmpsubtitles.c:192
+msgid "Armenian"
+msgstr "Armenisch"
+
+#: ../applet/cpmpsubtitles.c:194
+#: ../applet/cpmpsubtitles.c:195
+#: ../applet/cpmpsubtitles.c:196
+msgid "Baltic"
+msgstr "Baltisch"
+
+#: ../applet/cpmpsubtitles.c:198
+msgid "Celtic"
+msgstr "Keltisch"
+
+#: ../applet/cpmpsubtitles.c:200
+#: ../applet/cpmpsubtitles.c:201
+#: ../applet/cpmpsubtitles.c:202
+#: ../applet/cpmpsubtitles.c:203
+msgid "Central European"
+msgstr "Zentraleuropäisch"
+
+#: ../applet/cpmpsubtitles.c:205
+#: ../applet/cpmpsubtitles.c:206
+#: ../applet/cpmpsubtitles.c:207
+#: ../applet/cpmpsubtitles.c:208
+msgid "Chinese Simplified"
+msgstr "Vereinfachtes Chinesisch"
+
+#: ../applet/cpmpsubtitles.c:210
+#: ../applet/cpmpsubtitles.c:211
+#: ../applet/cpmpsubtitles.c:212
+msgid "Chinese Traditional"
+msgstr "Traditionelles Chinesisch"
+
+#: ../applet/cpmpsubtitles.c:214
+msgid "Croatian"
+msgstr "Kroatisch"
+
+#: ../applet/cpmpsubtitles.c:216
+#: ../applet/cpmpsubtitles.c:217
+#: ../applet/cpmpsubtitles.c:218
+#: ../applet/cpmpsubtitles.c:219
+#: ../applet/cpmpsubtitles.c:220
+#: ../applet/cpmpsubtitles.c:221
+msgid "Cyrillic"
+msgstr "Kyrillisch"
+
+#: ../applet/cpmpsubtitles.c:223
+msgid "Cyrillic/Russian"
+msgstr "Kyrillisch/Russisch"
+
+#: ../applet/cpmpsubtitles.c:225
+#: ../applet/cpmpsubtitles.c:226
+msgid "Cyrillic/Ukrainian"
+msgstr "Kyrillisch/Ukrainisch"
+
+#: ../applet/cpmpsubtitles.c:228
+msgid "Georgian"
+msgstr "Georgisch"
+
+#: ../applet/cpmpsubtitles.c:230
+#: ../applet/cpmpsubtitles.c:231
+#: ../applet/cpmpsubtitles.c:232
+msgid "Greek"
+msgstr "Griechisch"
+
+#: ../applet/cpmpsubtitles.c:234
+msgid "Gujarati"
+msgstr "Gujarati"
+
+#: ../applet/cpmpsubtitles.c:236
+msgid "Gurmukhi"
+msgstr "Gurmukhi"
+
+#: ../applet/cpmpsubtitles.c:238
+#: ../applet/cpmpsubtitles.c:239
+#: ../applet/cpmpsubtitles.c:240
+#: ../applet/cpmpsubtitles.c:241
+msgid "Hebrew"
+msgstr "Hebräisch"
+
+#: ../applet/cpmpsubtitles.c:243
+msgid "Hebrew Visual"
+msgstr "Visuelles Hebräisch"
+
+#: ../applet/cpmpsubtitles.c:245
+msgid "Hindi"
+msgstr "Hindi"
+
+#: ../applet/cpmpsubtitles.c:247
+msgid "Icelandic"
+msgstr "Isländisch"
+
+#: ../applet/cpmpsubtitles.c:249
+#: ../applet/cpmpsubtitles.c:250
+#: ../applet/cpmpsubtitles.c:251
+msgid "Japanese"
+msgstr "Japanisch"
+
+#: ../applet/cpmpsubtitles.c:253
+#: ../applet/cpmpsubtitles.c:254
+#: ../applet/cpmpsubtitles.c:255
+#: ../applet/cpmpsubtitles.c:256
+msgid "Korean"
+msgstr "Koreanisch"
+
+#: ../applet/cpmpsubtitles.c:258
+msgid "Nordic"
+msgstr "Nordisch"
+
+#: ../applet/cpmpsubtitles.c:260
+msgid "Persian"
+msgstr "Persisch"
+
+#: ../applet/cpmpsubtitles.c:262
+#: ../applet/cpmpsubtitles.c:263
+msgid "Romanian"
+msgstr "Rumänisch"
+
+#: ../applet/cpmpsubtitles.c:265
+msgid "South European"
+msgstr "Südeuropäisch"
+
+#: ../applet/cpmpsubtitles.c:267
+msgid "Thai"
+msgstr "Thai"
+
+#: ../applet/cpmpsubtitles.c:269
+#: ../applet/cpmpsubtitles.c:270
+#: ../applet/cpmpsubtitles.c:271
+#: ../applet/cpmpsubtitles.c:272
+msgid "Turkish"
+msgstr "Türkisch"
+
+#: ../applet/cpmpsubtitles.c:274
+#: ../applet/cpmpsubtitles.c:275
+#: ../applet/cpmpsubtitles.c:276
+#: ../applet/cpmpsubtitles.c:277
+#: ../applet/cpmpsubtitles.c:278
+msgid "Unicode"
+msgstr "Unicode"
+
+#: ../applet/cpmpsubtitles.c:280
+#: ../applet/cpmpsubtitles.c:281
+#: ../applet/cpmpsubtitles.c:282
+#: ../applet/cpmpsubtitles.c:283
+#: ../applet/cpmpsubtitles.c:284
+msgid "Western"
+msgstr "Westlich"
+
+#: ../applet/cpmpsubtitles.c:286
+#: ../applet/cpmpsubtitles.c:287
+#: ../applet/cpmpsubtitles.c:288
+msgid "Vietnamese"
+msgstr "Vietnamesisch"
+
+#: ../applet/cpmpsubtitles.c:290
+msgid "Current Locale"
+msgstr "Aktuelle Sprache/Region"
+
+#: ../applet/cpmpsubtitles.c:432
+#: ../applet/cpmpsubtitles.c:631
+msgid "Font"
+msgstr "Schrift"
+
+#: ../applet/cpmpsubtitles.c:602
+msgid "Automatically load subtitle files"
+msgstr "Untertiteldateien automatisch laden"
+
+#: ../applet/cpmpsubtitles.c:668
+msgid "Encoding"
+msgstr "Codierung"
+
+#: ../applet/cpmpsubtitles.c:733
+msgid "Subtitles"
+msgstr "Untertitel"
+
--- /dev/null
+# This is an fi_FI "translation" file for MAFW Gstreamer renderer with subtitles
+# support. To translate this to another language, first copy this file to a
+# filename with the appropriate language/country code, then modify the "msgstr"
+# strings with the correct translation.
+# Copyright (C) 2010, Marko Vertainen
+# This file is distributed under the same license as the MAFW Gstreamer renderer
+# with subtitles support package.
+# FIRST AUTHOR <marko.vertainen@iki.fi>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-04-21 04:04+0000\n"
+"PO-Revision-Date: 2010-02-02 16:46+0200\n"
+"Last-Translator: Marko Vertainen <marko.vertainen@iki.fi>\n"
+"Language-Team: FI <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../applet/cpmpsubtitles.c:59
+msgid "Regular"
+msgstr "Tavallinen"
+
+#: ../applet/cpmpsubtitles.c:60
+msgid "Italic"
+msgstr "Kursivoitu"
+
+#: ../applet/cpmpsubtitles.c:61
+msgid "Bold"
+msgstr "Lihavoitu"
+
+#: ../applet/cpmpsubtitles.c:62
+msgid "Italic Bold"
+msgstr "Lihavoitu kursiivi"
+
+#: ../applet/cpmpsubtitles.c:187 ../applet/cpmpsubtitles.c:188
+#: ../applet/cpmpsubtitles.c:189 ../applet/cpmpsubtitles.c:190
+msgid "Arabic"
+msgstr "Arabialainen"
+
+#: ../applet/cpmpsubtitles.c:192
+msgid "Armenian"
+msgstr "Armenialainen"
+
+#: ../applet/cpmpsubtitles.c:194 ../applet/cpmpsubtitles.c:195
+#: ../applet/cpmpsubtitles.c:196
+msgid "Baltic"
+msgstr "Balttialainen"
+
+#: ../applet/cpmpsubtitles.c:198
+msgid "Celtic"
+msgstr "Kelttiläinen"
+
+#: ../applet/cpmpsubtitles.c:200 ../applet/cpmpsubtitles.c:201
+#: ../applet/cpmpsubtitles.c:202 ../applet/cpmpsubtitles.c:203
+msgid "Central European"
+msgstr "Keskieurooppalainen"
+
+#: ../applet/cpmpsubtitles.c:205 ../applet/cpmpsubtitles.c:206
+#: ../applet/cpmpsubtitles.c:207 ../applet/cpmpsubtitles.c:208
+msgid "Chinese Simplified"
+msgstr "Kiinalainen, yksinkertaistettu"
+
+#: ../applet/cpmpsubtitles.c:210 ../applet/cpmpsubtitles.c:211
+#: ../applet/cpmpsubtitles.c:212
+msgid "Chinese Traditional"
+msgstr "Kiinalainen, perinteinen"
+
+#: ../applet/cpmpsubtitles.c:214
+msgid "Croatian"
+msgstr "Kroatialainen"
+
+#: ../applet/cpmpsubtitles.c:216 ../applet/cpmpsubtitles.c:217
+#: ../applet/cpmpsubtitles.c:218 ../applet/cpmpsubtitles.c:219
+#: ../applet/cpmpsubtitles.c:220 ../applet/cpmpsubtitles.c:221
+msgid "Cyrillic"
+msgstr "Kyriilinen"
+
+#: ../applet/cpmpsubtitles.c:223
+msgid "Cyrillic/Russian"
+msgstr "Kyriilinen/Venäläinen"
+
+#: ../applet/cpmpsubtitles.c:225 ../applet/cpmpsubtitles.c:226
+msgid "Cyrillic/Ukrainian"
+msgstr "Kyriilinen/Ukrainalainen"
+
+#: ../applet/cpmpsubtitles.c:228
+msgid "Georgian"
+msgstr "Georgialainen"
+
+#: ../applet/cpmpsubtitles.c:230 ../applet/cpmpsubtitles.c:231
+#: ../applet/cpmpsubtitles.c:232
+msgid "Greek"
+msgstr "Kreikkalainen"
+
+#: ../applet/cpmpsubtitles.c:234
+msgid "Gujarati"
+msgstr "Gujarati"
+
+#: ../applet/cpmpsubtitles.c:236
+msgid "Gurmukhi"
+msgstr "Gurmukhi"
+
+#: ../applet/cpmpsubtitles.c:238 ../applet/cpmpsubtitles.c:239
+#: ../applet/cpmpsubtitles.c:240 ../applet/cpmpsubtitles.c:241
+msgid "Hebrew"
+msgstr "Hebrealainen"
+
+#: ../applet/cpmpsubtitles.c:243
+msgid "Hebrew Visual"
+msgstr "Hebrealainen, visuaalinen"
+
+#: ../applet/cpmpsubtitles.c:245
+msgid "Hindi"
+msgstr "Hindilainen"
+
+#: ../applet/cpmpsubtitles.c:247
+msgid "Icelandic"
+msgstr "Islantilainen"
+
+#: ../applet/cpmpsubtitles.c:249 ../applet/cpmpsubtitles.c:250
+#: ../applet/cpmpsubtitles.c:251
+msgid "Japanese"
+msgstr "Japanilainen"
+
+#: ../applet/cpmpsubtitles.c:253 ../applet/cpmpsubtitles.c:254
+#: ../applet/cpmpsubtitles.c:255 ../applet/cpmpsubtitles.c:256
+msgid "Korean"
+msgstr "Korealainen"
+
+#: ../applet/cpmpsubtitles.c:258
+msgid "Nordic"
+msgstr "Pohjoismaalainen"
+
+#: ../applet/cpmpsubtitles.c:260
+msgid "Persian"
+msgstr "Persialainen"
+
+#: ../applet/cpmpsubtitles.c:262 ../applet/cpmpsubtitles.c:263
+msgid "Romanian"
+msgstr "Romanialainen"
+
+#: ../applet/cpmpsubtitles.c:265
+msgid "South European"
+msgstr "Eteläeurooppalainen"
+
+#: ../applet/cpmpsubtitles.c:267
+msgid "Thai"
+msgstr "Thaimaalainen"
+
+#: ../applet/cpmpsubtitles.c:269 ../applet/cpmpsubtitles.c:270
+#: ../applet/cpmpsubtitles.c:271 ../applet/cpmpsubtitles.c:272
+msgid "Turkish"
+msgstr "Turkkilainen"
+
+#: ../applet/cpmpsubtitles.c:274 ../applet/cpmpsubtitles.c:275
+#: ../applet/cpmpsubtitles.c:276 ../applet/cpmpsubtitles.c:277
+#: ../applet/cpmpsubtitles.c:278
+msgid "Unicode"
+msgstr "Unicode"
+
+#: ../applet/cpmpsubtitles.c:280 ../applet/cpmpsubtitles.c:281
+#: ../applet/cpmpsubtitles.c:282 ../applet/cpmpsubtitles.c:283
+#: ../applet/cpmpsubtitles.c:284
+msgid "Western"
+msgstr "Länsimainen"
+
+#: ../applet/cpmpsubtitles.c:286 ../applet/cpmpsubtitles.c:287
+#: ../applet/cpmpsubtitles.c:288
+msgid "Vietnamese"
+msgstr "Vietnamilainen"
+
+#: ../applet/cpmpsubtitles.c:290
+msgid "Current Locale"
+msgstr "Nykyinen maa-asetus"
+
+#: ../applet/cpmpsubtitles.c:432 ../applet/cpmpsubtitles.c:631
+msgid "Font"
+msgstr "Kirjasin"
+
+#: ../applet/cpmpsubtitles.c:602
+msgid "Automatically load subtitle files"
+msgstr "Lataa tekstitystiedosto automaattisesti"
+
+#: ../applet/cpmpsubtitles.c:668
+msgid "Encoding"
+msgstr "Merkistökoodaus"
+
+#: ../applet/cpmpsubtitles.c:733
+msgid "Subtitles"
+msgstr "Tekstitys"
--- /dev/null
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: subtitle hun loc\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-02-20 04:03+0000\n"
+"PO-Revision-Date: 2010-02-21 13:47-0000\n"
+"Last-Translator: Gyorgy Lakatos <redon13@gmail.com>\n"
+"Language-Team: Hungarian Translater Team <redon13@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Hungarian\n"
+"X-Poedit-Country: UNITED KINGDOM\n"
+
+#: ../applet/cpmpsubtitles.c:59
+msgid "Regular"
+msgstr "Szabályos"
+
+#: ../applet/cpmpsubtitles.c:60
+msgid "Italic"
+msgstr "Itáliai"
+
+#: ../applet/cpmpsubtitles.c:61
+msgid "Bold"
+msgstr "Félkövér"
+
+#: ../applet/cpmpsubtitles.c:62
+msgid "Italic Bold"
+msgstr "Itáliai félkövér"
+
+#: ../applet/cpmpsubtitles.c:187
+#: ../applet/cpmpsubtitles.c:188
+#: ../applet/cpmpsubtitles.c:189
+#: ../applet/cpmpsubtitles.c:190
+msgid "Arabic"
+msgstr "Arab"
+
+#: ../applet/cpmpsubtitles.c:192
+msgid "Armenian"
+msgstr "Armenian"
+
+#: ../applet/cpmpsubtitles.c:194
+#: ../applet/cpmpsubtitles.c:195
+#: ../applet/cpmpsubtitles.c:196
+msgid "Baltic"
+msgstr "Balti"
+
+#: ../applet/cpmpsubtitles.c:198
+msgid "Celtic"
+msgstr "Kelta"
+
+#: ../applet/cpmpsubtitles.c:200
+#: ../applet/cpmpsubtitles.c:201
+#: ../applet/cpmpsubtitles.c:202
+#: ../applet/cpmpsubtitles.c:203
+msgid "Central European"
+msgstr "Közép Európai"
+
+#: ../applet/cpmpsubtitles.c:205
+#: ../applet/cpmpsubtitles.c:206
+#: ../applet/cpmpsubtitles.c:207
+#: ../applet/cpmpsubtitles.c:208
+msgid "Chinese Simplified"
+msgstr "Kínai (egyszerü)"
+
+#: ../applet/cpmpsubtitles.c:210
+#: ../applet/cpmpsubtitles.c:211
+#: ../applet/cpmpsubtitles.c:212
+msgid "Chinese Traditional"
+msgstr "Kínai (hagyományos)"
+
+#: ../applet/cpmpsubtitles.c:214
+msgid "Croatian"
+msgstr "Horvát"
+
+#: ../applet/cpmpsubtitles.c:216
+#: ../applet/cpmpsubtitles.c:217
+#: ../applet/cpmpsubtitles.c:218
+#: ../applet/cpmpsubtitles.c:219
+#: ../applet/cpmpsubtitles.c:220
+#: ../applet/cpmpsubtitles.c:221
+msgid "Cyrillic"
+msgstr "Ciril"
+
+#: ../applet/cpmpsubtitles.c:223
+msgid "Cyrillic/Russian"
+msgstr "Ciril/Orosz"
+
+#: ../applet/cpmpsubtitles.c:225
+#: ../applet/cpmpsubtitles.c:226
+msgid "Cyrillic/Ukrainian"
+msgstr "Ciril/Ukrán"
+
+#: ../applet/cpmpsubtitles.c:228
+msgid "Georgian"
+msgstr "Georgian"
+
+#: ../applet/cpmpsubtitles.c:230
+#: ../applet/cpmpsubtitles.c:231
+#: ../applet/cpmpsubtitles.c:232
+msgid "Greek"
+msgstr "Görög"
+
+#: ../applet/cpmpsubtitles.c:234
+msgid "Gujarati"
+msgstr "Gujarati"
+
+#: ../applet/cpmpsubtitles.c:236
+msgid "Gurmukhi"
+msgstr "Gurmukhi"
+
+#: ../applet/cpmpsubtitles.c:238
+#: ../applet/cpmpsubtitles.c:239
+#: ../applet/cpmpsubtitles.c:240
+#: ../applet/cpmpsubtitles.c:241
+msgid "Hebrew"
+msgstr "Héber"
+
+#: ../applet/cpmpsubtitles.c:243
+msgid "Hebrew Visual"
+msgstr "Héber (hagyományos)"
+
+#: ../applet/cpmpsubtitles.c:245
+msgid "Hindi"
+msgstr "Hindi"
+
+#: ../applet/cpmpsubtitles.c:247
+msgid "Icelandic"
+msgstr "Izlandi"
+
+#: ../applet/cpmpsubtitles.c:249
+#: ../applet/cpmpsubtitles.c:250
+#: ../applet/cpmpsubtitles.c:251
+msgid "Japanese"
+msgstr "Japán"
+
+#: ../applet/cpmpsubtitles.c:253
+#: ../applet/cpmpsubtitles.c:254
+#: ../applet/cpmpsubtitles.c:255
+#: ../applet/cpmpsubtitles.c:256
+msgid "Korean"
+msgstr "Koreai"
+
+#: ../applet/cpmpsubtitles.c:258
+msgid "Nordic"
+msgstr "Nordic"
+
+#: ../applet/cpmpsubtitles.c:260
+msgid "Persian"
+msgstr "Perzsa"
+
+#: ../applet/cpmpsubtitles.c:262
+#: ../applet/cpmpsubtitles.c:263
+msgid "Romanian"
+msgstr "Román"
+
+#: ../applet/cpmpsubtitles.c:265
+msgid "South European"
+msgstr "Dél Európai"
+
+#: ../applet/cpmpsubtitles.c:267
+msgid "Thai"
+msgstr "Thai"
+
+#: ../applet/cpmpsubtitles.c:269
+#: ../applet/cpmpsubtitles.c:270
+#: ../applet/cpmpsubtitles.c:271
+#: ../applet/cpmpsubtitles.c:272
+msgid "Turkish"
+msgstr "Török"
+
+#: ../applet/cpmpsubtitles.c:274
+#: ../applet/cpmpsubtitles.c:275
+#: ../applet/cpmpsubtitles.c:276
+#: ../applet/cpmpsubtitles.c:277
+#: ../applet/cpmpsubtitles.c:278
+msgid "Unicode"
+msgstr "Unicode"
+
+#: ../applet/cpmpsubtitles.c:280
+#: ../applet/cpmpsubtitles.c:281
+#: ../applet/cpmpsubtitles.c:282
+#: ../applet/cpmpsubtitles.c:283
+#: ../applet/cpmpsubtitles.c:284
+msgid "Western"
+msgstr "Nyugati"
+
+#: ../applet/cpmpsubtitles.c:286
+#: ../applet/cpmpsubtitles.c:287
+#: ../applet/cpmpsubtitles.c:288
+msgid "Vietnamese"
+msgstr "Vietnám"
+
+#: ../applet/cpmpsubtitles.c:290
+msgid "Current Locale"
+msgstr "Helyi"
+
+#: ../applet/cpmpsubtitles.c:432
+#: ../applet/cpmpsubtitles.c:631
+msgid "Font"
+msgstr "Betű méret"
+
+#: ../applet/cpmpsubtitles.c:602
+msgid "Automatically load subtitle files"
+msgstr "Autómatikus felirat file megnyitás"
+
+#: ../applet/cpmpsubtitles.c:668
+msgid "Encoding"
+msgstr "Kódolás"
+
+#: ../applet/cpmpsubtitles.c:733
+msgid "Subtitles"
+msgstr "Felirat"
+
--- /dev/null
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Roman Moravčík <roman.moravcik@gmail.com>, 2010.
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: mafw-gst-subtitles-renderer\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-18 14:36+0100\n"
+"PO-Revision-Date: 2010-01-19 09:52+0100\n"
+"Last-Translator: Roman Moravčík <roman.moravcik@gmail.com>\n"
+"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../applet/cpmpsubtitles.c:56
+msgid "Regular"
+msgstr "Normálne"
+
+#: ../applet/cpmpsubtitles.c:57
+msgid "Italic"
+msgstr "Kurzíva"
+
+#: ../applet/cpmpsubtitles.c:58
+msgid "Bold"
+msgstr "Tučné"
+
+#: ../applet/cpmpsubtitles.c:59
+msgid "Italic Bold"
+msgstr "Tučné kurzíva"
+
+#: ../applet/cpmpsubtitles.c:184
+msgid "Current Locale"
+msgstr "Súčasné miestne"
+
+#: ../applet/cpmpsubtitles.c:186 ../applet/cpmpsubtitles.c:187
+#: ../applet/cpmpsubtitles.c:188 ../applet/cpmpsubtitles.c:189
+msgid "Arabic"
+msgstr "Arabské"
+
+#: ../applet/cpmpsubtitles.c:191
+msgid "Armenian"
+msgstr "Arménske"
+
+#: ../applet/cpmpsubtitles.c:193 ../applet/cpmpsubtitles.c:194
+#: ../applet/cpmpsubtitles.c:195
+msgid "Baltic"
+msgstr "Baltské"
+
+#: ../applet/cpmpsubtitles.c:197
+msgid "Celtic"
+msgstr "Keltské"
+
+#: ../applet/cpmpsubtitles.c:199 ../applet/cpmpsubtitles.c:200
+#: ../applet/cpmpsubtitles.c:201 ../applet/cpmpsubtitles.c:202
+msgid "Central European"
+msgstr "Stredná Európa"
+
+#: ../applet/cpmpsubtitles.c:204 ../applet/cpmpsubtitles.c:205
+#: ../applet/cpmpsubtitles.c:206 ../applet/cpmpsubtitles.c:207
+msgid "Chinese Simplified"
+msgstr "Zjednodušené čínske"
+
+#: ../applet/cpmpsubtitles.c:209 ../applet/cpmpsubtitles.c:210
+#: ../applet/cpmpsubtitles.c:211
+msgid "Chinese Traditional"
+msgstr "Tradičné čínske"
+
+#: ../applet/cpmpsubtitles.c:213
+msgid "Croatian"
+msgstr "Chorvátske"
+
+#: ../applet/cpmpsubtitles.c:215 ../applet/cpmpsubtitles.c:216
+#: ../applet/cpmpsubtitles.c:217 ../applet/cpmpsubtitles.c:218
+#: ../applet/cpmpsubtitles.c:219 ../applet/cpmpsubtitles.c:220
+msgid "Cyrillic"
+msgstr "Cyrilika"
+
+#: ../applet/cpmpsubtitles.c:222
+msgid "Cyrillic/Russian"
+msgstr "Cyrilika/Ruské"
+
+#: ../applet/cpmpsubtitles.c:224 ../applet/cpmpsubtitles.c:225
+msgid "Cyrillic/Ukrainian"
+msgstr "Cyrilika/Ukrajinské"
+
+#: ../applet/cpmpsubtitles.c:227
+msgid "Georgian"
+msgstr "Gruzínske"
+
+#: ../applet/cpmpsubtitles.c:229 ../applet/cpmpsubtitles.c:230
+#: ../applet/cpmpsubtitles.c:231
+msgid "Greek"
+msgstr "Grécke"
+
+#: ../applet/cpmpsubtitles.c:233
+msgid "Gujarati"
+msgstr "Gudžarátske"
+
+#: ../applet/cpmpsubtitles.c:235
+msgid "Gurmukhi"
+msgstr "Chorvátske"
+
+#: ../applet/cpmpsubtitles.c:237 ../applet/cpmpsubtitles.c:238
+#: ../applet/cpmpsubtitles.c:239 ../applet/cpmpsubtitles.c:240
+msgid "Hebrew"
+msgstr "Chorvátske"
+
+#: ../applet/cpmpsubtitles.c:242
+msgid "Hebrew Visual"
+msgstr "Hebrejské vizuálne"
+
+#: ../applet/cpmpsubtitles.c:244
+msgid "Hindi"
+msgstr "Hindustánske"
+
+#: ../applet/cpmpsubtitles.c:246
+msgid "Icelandic"
+msgstr "Islandské"
+
+#: ../applet/cpmpsubtitles.c:248 ../applet/cpmpsubtitles.c:249
+#: ../applet/cpmpsubtitles.c:250
+msgid "Japanese"
+msgstr "Japonské"
+
+#: ../applet/cpmpsubtitles.c:252 ../applet/cpmpsubtitles.c:253
+#: ../applet/cpmpsubtitles.c:254 ../applet/cpmpsubtitles.c:255
+msgid "Korean"
+msgstr "Kórejské"
+
+#: ../applet/cpmpsubtitles.c:257
+msgid "Nordic"
+msgstr "Severogermánske"
+
+#: ../applet/cpmpsubtitles.c:259
+msgid "Persian"
+msgstr "Perzské"
+
+#: ../applet/cpmpsubtitles.c:261 ../applet/cpmpsubtitles.c:262
+msgid "Romanian"
+msgstr "Rumunské"
+
+#: ../applet/cpmpsubtitles.c:264
+msgid "South European"
+msgstr "Južná Európa"
+
+#: ../applet/cpmpsubtitles.c:266
+msgid "Thai"
+msgstr "Thajské"
+
+#: ../applet/cpmpsubtitles.c:268 ../applet/cpmpsubtitles.c:269
+#: ../applet/cpmpsubtitles.c:270 ../applet/cpmpsubtitles.c:271
+msgid "Turkish"
+msgstr "Turecké"
+
+#: ../applet/cpmpsubtitles.c:273 ../applet/cpmpsubtitles.c:274
+#: ../applet/cpmpsubtitles.c:275 ../applet/cpmpsubtitles.c:276
+#: ../applet/cpmpsubtitles.c:277
+msgid "Unicode"
+msgstr "Unicode"
+
+#: ../applet/cpmpsubtitles.c:279 ../applet/cpmpsubtitles.c:280
+#: ../applet/cpmpsubtitles.c:281 ../applet/cpmpsubtitles.c:282
+#: ../applet/cpmpsubtitles.c:283
+msgid "Western"
+msgstr "Západné"
+
+#: ../applet/cpmpsubtitles.c:285 ../applet/cpmpsubtitles.c:286
+#: ../applet/cpmpsubtitles.c:287
+msgid "Vietnamese"
+msgstr "Vietnamské"
+
+#: ../applet/cpmpsubtitles.c:424 ../applet/cpmpsubtitles.c:584
+msgid "Font"
+msgstr "Písmo"
+
+#: ../applet/cpmpsubtitles.c:555
+msgid "Automatically load subtitle files"
+msgstr "Automaticky načítať súbor s titulkami"
+
+#: ../applet/cpmpsubtitles.c:620
+msgid "Encoding"
+msgstr "Kódovanie"
+
+#: ../applet/cpmpsubtitles.c:685
+msgid "Subtitles"
+msgstr "Titulky"
--- /dev/null
+#
+# Makefile.am for MAFW gst renderer library.
+#
+# Author: Visa Smolander <visa.smolander@nokia.com>
+#
+# Copyright (C) 2007, 2008, 2009 Nokia. All rights reserved.
+
+TESTS = check-mafw-gst-renderer
+TESTS_ENVIRONMENT = CK_FORK=yes \
+ TESTS_DIR=@abs_srcdir@
+
+noinst_PROGRAMS = $(TESTS)
+
+AM_CFLAGS = $(_CFLAGS)
+AM_LDFLAGS = $(_LDFLAGS)
+
+INCLUDES = -I$(top_srcdir)/libmafw-gst-renderer \
+ $(DEPS_CFLAGS) \
+ $(DEPS_TESTS_CFLAGS) \
+ $(CHECKMORE_CFLAGS)
+
+LDADD = $(CHECKMORE_LIBS) \
+ $(DEPS_LIBS) \
+ $(DEPS_TESTS_LIBS) \
+ $(top_builddir)/libmafw-gst-renderer/mafw-gst-renderer.la \
+ -lgstinterfaces-0.10 -lgsttag-0.10
+
+if HAVE_GDKPIXBUF
+INCLUDES += $(GDKPIXBUF_CFLAGS)
+LDADD += $(GDKPIXBUF_LIBS)
+endif
+
+if HAVE_CONIC
+INCLUDES += $(CONIC_CFLAGS)
+LDADD += $(CONIC_LIBS)
+endif
+
+EXTRA_DIST = media/test.wav media/test.avi media/testframe.png
+
+# -----------------------------------------------
+# Test programs build specs
+# -----------------------------------------------
+
+check_mafw_gst_renderer_SOURCES = check-main.c \
+ check-mafw-gst-renderer.c \
+ mafw-mock-playlist.c mafw-mock-playlist.h \
+ mafw-mock-pulseaudio.c mafw-mock-pulseaudio.h
+
+CLEANFILES = $(TESTS) mafw.db *.gcno *.gcda
+MAINTAINERCLEANFILES = Makefile.in
+
+# Run valgrind on tests.
+VG_OPTS := --suppressions=test.suppressions --tool=memcheck \
+ --leak-check=full --show-reachable=yes
+vg: $(TESTS)
+ for p in $^; do \
+ G_SLICE=always-malloc G_DEBUG=gc-friendly WAIT_TIMEOUT=25000 \
+ libtool --mode=execute valgrind $(VG_OPTS) $$p 2>vglog.$$p; \
+ done;
+ -rm -f vgcore.*
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * check-gst-renderer.c
+ *
+ * Gst Renderer unit tests
+ *
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ */
+
+#include <glib.h>
+
+#include <check.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sqlite3.h>
+#include <gst/tag/tag.h>
+
+#include <libmafw/mafw.h>
+#include <checkmore.h>
+
+#include "config.h"
+
+#include "mafw-gst-renderer.h"
+#include "mafw-mock-playlist.h"
+#include "mafw-mock-pulseaudio.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "check-mafw-gstreamer-renderer"
+
+#define SAMPLE_AUDIO_CLIP "test.wav"
+#define SAMPLE_VIDEO_CLIP "test.avi"
+#define SAMPLE_IMAGE "testframe.png"
+
+/* Base timeout used when waiting for state transitions or execution of
+ user function callbacks associated to each mafw-renderer function */
+#define DEFAULT_WAIT_TOUT 2000
+
+/* EOS timeout must be longer than the clip duration */
+#define EOS_TIMEOUT 7000
+
+SRunner *configure_tests(void);
+
+typedef struct {
+ gint index;
+ MafwPlayState state;
+} RendererInfo;
+
+typedef struct {
+ gboolean called;
+ gboolean error;
+ gint err_code;
+ gchar *err_msg;
+ gint seek_position;
+ gboolean error_signal_expected;
+ GError *error_signal_received;
+ const gchar *property_expected;
+ GValue *property_received;
+} CallbackInfo;
+
+typedef struct {
+ const gchar *expected_key;
+ GValue *value;
+} MetadataChangedInfo;
+
+typedef struct {
+ const gchar *expected;
+ GValue *received;
+} PropertyChangedInfo;
+
+typedef struct {
+ gboolean requested;
+ gboolean received;
+ gfloat value;
+} BufferingInfo;
+
+static gint wait_tout_val;
+
+/* Globals. */
+
+static MafwRenderer *g_gst_renderer = NULL;
+
+/* Error messages. */
+
+static const gchar *callback_err_msg = "Error received when %s: (%d) %s";
+static const gchar *callback_no_err_msg = "No error received when %s: (%d) %s";
+static const gchar *no_callback_msg = "We forgot to call the user callback";
+static const gchar *state_err_msg = "Call %s didn't change state to %s. " \
+"Current state is: %d";
+static const gchar *index_err_msg = "Actual index is (%d) instead of the " \
+"expected index (%d)";
+
+
+/*----------------------------------------------------------------------------
+ Signal handlers
+ ----------------------------------------------------------------------------*/
+
+
+static void error_cb(MafwRenderer *s, GQuark domain, gint code, gchar *msg,
+ gpointer user_data)
+{
+ CallbackInfo* c = (CallbackInfo*) user_data;
+
+ /* "MafwExtension::error" signal handler */
+ if (user_data == NULL || !c->error_signal_expected) {
+ fail("Signal error received: (%d) %s", code, msg);
+ } else {
+ if (c->error_signal_received != NULL) {
+ fail("Error received already initialized");
+ } else {
+ c->error_signal_received =
+ g_error_new_literal(domain, code, msg);
+ }
+ }
+}
+
+static void state_changed_cb(MafwRenderer *s, MafwPlayState state,
+ gpointer user_data)
+{
+ /* "MafwRenderer::state-changed" signal handler */
+ RendererInfo *si = (RendererInfo *) user_data;
+ gchar *states[] = {"Stopped","Playing","Paused","Transitioning"};
+
+ si->state = state;
+ g_debug("state changed (%s) ---", states[state]);
+}
+
+static gboolean media_changed_called;
+
+static void media_changed_cb(MafwRenderer *s, gint index, gchar *objectid,
+ gpointer user_data)
+{
+ /* "MafwRenderer::media-changed" signal handler */
+ RendererInfo *si = (RendererInfo *) user_data;
+
+ si->index = index;
+ g_debug("media changed (%d) ---", index);
+ media_changed_called = TRUE;
+}
+static void playlist_changed_cb (MafwRenderer *self,
+ GObject *playlist,
+ gpointer user_data)
+{
+ g_debug("playlist changed");
+ fail_if(media_changed_called, "At first playlist-changed should be called");
+}
+
+static void metadata_changed_cb(MafwRenderer *self, const gchar *key,
+ GValueArray *value, gpointer user_data)
+{
+ MetadataChangedInfo *m = user_data;
+
+ if (m->expected_key != NULL && strcmp(key, m->expected_key) == 0)
+ {
+ GValue *original;
+
+ original = g_value_array_get_nth(value, 0);
+
+ m->value = g_new0(GValue, 1);
+ g_value_init(m->value, G_VALUE_TYPE(original));
+ g_value_copy(original, m->value);
+ }
+}
+
+static void property_changed_cb(MafwExtension *extension, const gchar *name,
+ const GValue *value, gpointer user_data)
+{
+ PropertyChangedInfo* p = (PropertyChangedInfo*) user_data;
+ gchar *value_string;
+
+ value_string = g_strdup_value_contents(value);
+
+ g_debug("property_changed_cb: %s (%s)", name, value_string);
+ g_free(value_string);
+
+ if (p->expected != NULL &&
+ strcmp(p->expected, name) == 0) {
+ p->received = g_new0(GValue, 1);
+ g_value_init(p->received, G_VALUE_TYPE(value));
+ g_value_copy(value, p->received);
+ }
+}
+
+static void buffering_info_cb(MafwRenderer *self, gfloat status,
+ gpointer user_data)
+{
+ BufferingInfo *b = user_data;
+
+ if (b->requested) {
+ b->received = TRUE;
+ b->value = status;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Function callbacks
+ ----------------------------------------------------------------------------*/
+
+
+static void status_cb(MafwRenderer* renderer, MafwPlaylist* playlist, guint index,
+ MafwPlayState state,
+ const gchar* object_id,
+ gpointer user_data,
+ const GError *error)
+{
+ /* MafwRendererStatusCB */
+ RendererInfo* s = (RendererInfo*) user_data;
+ g_assert(s != NULL);
+
+ if (error != NULL) {
+ fail("Error received while trying to get renderer status: (%d) %s",
+ error->code, error->message);
+ }
+ s->state = state;
+
+}
+
+static void playback_cb(MafwRenderer* renderer, gpointer user_data, const GError* error)
+{
+ /* MafwRendererPlaybackCB:
+
+ Called after mafw_renderer_play(), mafw_renderer_play_uri(),
+ mafw_renderer_play_object(), mafw_renderer_stop(), mafw_renderer_pause(),
+ mafw_renderer_resume(), mafw_renderer_next(), mafw_renderer_previous() or
+ mafw_renderer_goto_index() has been called. */
+ CallbackInfo* c = (CallbackInfo*) user_data;
+ g_assert(c != NULL);
+
+ c->called = TRUE;
+ if (error != NULL) {
+ c->error = TRUE;
+ c->err_code = error->code;
+ c->err_msg = g_strdup(error->message);
+ }
+}
+
+static void seek_cb (MafwRenderer *self, gint position, gpointer user_data,
+ const GError *error)
+{
+ /* Called when seeking */
+
+ CallbackInfo* c = (CallbackInfo*) user_data;
+ g_assert(c != NULL);
+
+ c->called = TRUE;
+ c->seek_position = position;
+ if (error != NULL) {
+ c->error = TRUE;
+ c->err_code = error->code;
+ c->err_msg = g_strdup(error->message);
+ }
+}
+
+static void get_position_cb(MafwRenderer *self, gint position,
+ gpointer user_data, const GError *error)
+{
+ CallbackInfo* c = (CallbackInfo*) user_data;
+
+ g_debug("get position cb: %d", position);
+
+ if (error != NULL) {
+ c->error = TRUE;
+ c->err_code = error->code;
+ c->err_msg = g_strdup(error->message);
+ }
+ c->called = TRUE;
+}
+
+static void get_property_cb(MafwExtension *self,
+ const gchar *name,
+ GValue *value,
+ gpointer user_data,
+ const GError *error)
+{
+ CallbackInfo* c = (CallbackInfo*) user_data;
+ gchar *value_string;
+
+ value_string = g_strdup_value_contents(value);
+
+ g_debug("get property cb: %s (%s)", name, value_string);
+ g_free(value_string);
+
+ if (error != NULL) {
+ c->error = TRUE;
+ c->err_code = error->code;
+ c->err_msg = g_strdup(error->message);
+ }
+
+ if (c->property_expected != NULL &&
+ strcmp(c->property_expected, name) == 0) {
+ c->property_received = g_new0(GValue, 1);
+ g_value_init(c->property_received, G_VALUE_TYPE(value));
+ g_value_copy(value, c->property_received);
+
+ c->called = TRUE;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Helpers
+ ----------------------------------------------------------------------------*/
+
+static gchar *get_sample_clip_path(const gchar *clip)
+{
+ gchar *my_dir, *media;
+
+ /* Makefile.am sets TESTS_DIR, required for VPATH builds (like make
+ * distcheck). Otherwise assume we are running in-place. */
+ my_dir = g_strdup(g_getenv("TESTS_DIR"));
+ if (!my_dir)
+ my_dir = g_get_current_dir();
+ media = g_strconcat("file://", my_dir, G_DIR_SEPARATOR_S,
+ "media" G_DIR_SEPARATOR_S, clip,
+ NULL);
+ g_free(my_dir);
+ return media;
+}
+
+static gchar *get_sample_clip_objectid(const gchar *clip)
+{
+ gchar *path = NULL;
+ gchar *objectid = NULL;
+
+ path = get_sample_clip_path(clip);
+ objectid = mafw_source_create_objectid(path);
+ g_free(path);
+
+ return objectid;
+}
+
+static gboolean stop_wait_timeout(gpointer user_data)
+{
+ gboolean *do_stop = (gboolean *) user_data;
+ g_debug("stop wait timeout");
+ *do_stop = TRUE;
+
+ return FALSE;
+}
+
+static gboolean wait_until_timeout_finishes(guint millis)
+{
+ guint timeout = 0;
+ gboolean stop_wait = FALSE;
+ gboolean result = FALSE;
+
+ g_debug("Init wait_");
+ /* We'll wait a limitted ammount of time */
+ timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
+ while(!stop_wait) {
+ result= g_main_context_iteration(NULL, TRUE);
+ }
+
+ g_debug("End wait_");
+ return TRUE;
+}
+
+static gboolean wait_for_state(RendererInfo *renderer_info,
+ MafwPlayState expected_state, guint millis)
+{
+ guint timeout = 0;
+ gboolean stop_wait = FALSE;
+
+ g_debug("Init wait for state");
+ /* We'll wait a limitted ammount of time */
+ timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
+
+ while(renderer_info->state != expected_state && !stop_wait) {
+ g_main_context_iteration(NULL, TRUE);
+ }
+
+ if (!stop_wait) {
+ g_source_remove(timeout);
+ }
+
+ g_debug("End wait for state");
+ return (renderer_info->state == expected_state);
+}
+
+static gboolean wait_for_callback(CallbackInfo *callback, guint millis)
+{
+ guint timeout = 0;
+ gboolean stop_wait = FALSE;
+
+ g_debug("Init wait for callback");
+ /* We'll wait a limitted ammount of time */
+ timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
+
+ while (callback->called == FALSE && !stop_wait) {
+ g_main_context_iteration(NULL, TRUE);
+ }
+ if (!stop_wait) {
+ g_source_remove(timeout);
+ }
+ g_debug("End wait for callback");
+ return callback->called;
+}
+
+static gboolean wait_for_metadata(MetadataChangedInfo *callback, guint millis)
+{
+ guint timeout = 0;
+ gboolean stop_wait = FALSE;
+
+ g_debug("Init wait for metadata");
+ /* We'll wait a limitted ammount of time */
+ timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
+
+ while (callback->value == NULL && !stop_wait) {
+ g_main_context_iteration(NULL, TRUE);
+ }
+ if (!stop_wait) {
+ g_source_remove(timeout);
+ }
+ g_debug("End wait for metadata");
+ return callback->value != NULL;
+}
+
+static gboolean wait_for_property(PropertyChangedInfo *callback, guint millis)
+{
+ guint timeout = 0;
+ gboolean stop_wait = FALSE;
+
+ g_debug("Init wait for property changed");
+ /* We'll wait a limitted ammount of time */
+ timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
+
+ while (callback->received == NULL && !stop_wait) {
+ g_main_context_iteration(NULL, TRUE);
+ }
+ if (!stop_wait) {
+ g_source_remove(timeout);
+ }
+ g_debug("End wait for callback");
+ return callback->received != NULL;
+}
+
+static gboolean wait_for_buffering(BufferingInfo *callback, guint millis)
+{
+ guint timeout = 0;
+ gboolean stop_wait = FALSE;
+
+ g_debug("Init wait for buffering info");
+ /* We'll wait a limitted ammount of time */
+ timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
+
+ while (!callback->received && !stop_wait) {
+ g_main_context_iteration(NULL, TRUE);
+ }
+ if (!stop_wait) {
+ g_source_remove(timeout);
+ }
+ g_debug("End wait for buffering info");
+ return callback->received;
+}
+
+static void reset_callback_info(CallbackInfo *callback_info)
+{
+ if (callback_info->err_msg != NULL)
+ g_free(callback_info->err_msg);
+
+ callback_info->err_msg = NULL;
+ callback_info->called = FALSE;
+ callback_info->error = FALSE;
+ callback_info->seek_position = 0;
+ callback_info->error_signal_expected = FALSE;
+ if (callback_info->error_signal_received != NULL) {
+ g_error_free(callback_info->error_signal_received);
+ callback_info->error_signal_received = NULL;
+ }
+ callback_info->property_expected = NULL;
+ if (callback_info->property_received != NULL) {
+ g_value_unset(callback_info->property_received);
+ callback_info->property_received = NULL;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Fixtures
+ ----------------------------------------------------------------------------*/
+
+static void fx_setup_dummy_gst_renderer(void)
+{
+ MafwRegistry *registry;
+
+ /* Setup GLib */
+ g_type_init();
+
+ /* Create a gst renderer instance */
+ registry = MAFW_REGISTRY(mafw_registry_get_instance());
+ fail_if(registry == NULL,
+ "Error: cannot get MAFW registry");
+
+ g_gst_renderer = MAFW_RENDERER(mafw_gst_renderer_new(registry));
+ fail_if(!MAFW_IS_GST_RENDERER(g_gst_renderer),
+ "Could not create gst renderer instance");
+}
+
+static void fx_teardown_dummy_gst_renderer(void)
+{
+ g_object_unref(g_gst_renderer);
+}
+
+/*----------------------------------------------------------------------------
+ Mockups
+ ----------------------------------------------------------------------------*/
+
+/* GStreamer mock */
+
+GstElement * gst_element_factory_make(const gchar * factoryname,
+ const gchar * name)
+{
+ GstElementFactory *factory;
+ GstElement *element;
+ const gchar *use_factoryname;
+
+ g_return_val_if_fail(factoryname != NULL, NULL);
+
+ /* For testing, use playbin instead of playbin2 */
+ if (g_ascii_strcasecmp(factoryname, "playbin2") == 0)
+ use_factoryname = "playbin";
+ else
+ use_factoryname = factoryname;
+
+ GST_LOG("gstelementfactory: make \"%s\" \"%s\"",
+ use_factoryname, GST_STR_NULL (name));
+
+ factory = gst_element_factory_find(use_factoryname);
+ if (factory == NULL) {
+ /* No factory */
+ GST_INFO("no such element factory \"%s\"!", use_factoryname);
+ return NULL;
+ }
+
+ GST_LOG_OBJECT(factory, "found factory %p", factory);
+ if (g_ascii_strcasecmp(use_factoryname, "pulsesink") == 0) {
+ element = gst_element_factory_make("fakesink", "pulsesink");
+ g_object_set(G_OBJECT(element), "sync", TRUE, NULL);
+ } else if (g_ascii_strcasecmp(use_factoryname, "xvimagesink") == 0) {
+ element = gst_element_factory_make("fakesink", "xvimagesink");
+ g_object_set(G_OBJECT(element), "sync", TRUE, NULL);
+ } else {
+ element = gst_element_factory_create(factory, name);
+ }
+ gst_object_unref(factory);
+
+ if (element == NULL) {
+ /* Create failed */
+ GST_INFO_OBJECT(factory, "couldn't create instance!");
+ return NULL;
+ }
+
+ GST_LOG("gstelementfactory: make \"%s\" \"%s\"",use_factoryname,
+ GST_STR_NULL(name));
+
+ /* Playbin will use fake renderer */
+ if (g_ascii_strcasecmp(use_factoryname, "playbin") == 0) {
+ GstElement *audiorenderer = gst_element_factory_make("fakesink",
+ "audiorenderer");
+
+ g_object_set(G_OBJECT(audiorenderer), "sync", TRUE, NULL);
+ g_object_set(G_OBJECT(element),
+ "audio-sink",
+ audiorenderer,
+ NULL);
+ g_object_set(G_OBJECT(element),
+ "video-sink",
+ audiorenderer,
+ NULL);
+ }
+
+ return element;
+}
+
+
+/*----------------------------------------------------------------------------
+ Test cases
+ ----------------------------------------------------------------------------*/
+
+START_TEST(test_basic_playback)
+{
+ RendererInfo s;
+ CallbackInfo c;
+ MetadataChangedInfo m;
+ GstBus *bus = NULL;
+ GstMessage *message = NULL;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ m.expected_key = NULL;
+ m.value = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "metadata-changed",
+ G_CALLBACK(metadata_changed_cb),
+ &m);
+
+ /* --- Get initial status --- */
+
+ reset_callback_info(&c);
+
+ g_debug("get status...");
+ mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
+
+ /* --- Play --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ /* No media item has been set so, we should get an error */
+ if (c.error == FALSE)
+ fail("Play of unset media did not return an error");
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ gchar *objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
+
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Transitioning",
+ s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ g_free(objectid);
+
+ /* --- Get position --- */
+
+ reset_callback_info(&c);
+
+ mafw_renderer_get_position(g_gst_renderer, get_position_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "get_position", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Duration emission --- */
+
+ m.expected_key = MAFW_METADATA_KEY_DURATION;
+
+ bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus;
+ fail_if(bus == NULL, "No GstBus");
+
+ message = gst_message_new_duration(NULL, GST_FORMAT_TIME,
+ 5 * GST_SECOND);
+ gst_bus_post(bus, message);
+
+ if (wait_for_metadata(&m, wait_tout_val) == FALSE) {
+ fail("Expected " MAFW_METADATA_KEY_DURATION
+ ", but not received");
+ }
+
+ fail_if(m.value == NULL, "Metadata " MAFW_METADATA_KEY_DURATION
+ " not received");
+
+ g_value_unset(m.value);
+ g_free(m.value);
+ m.value = NULL;
+ m.expected_key = NULL;
+
+ /* --- Pause --- */
+
+ reset_callback_info(&c);
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_pause", "Paused", s.state);
+ }
+
+ /* --- Resume --- */
+
+ reset_callback_info(&c);
+
+ g_debug("resume...");
+ mafw_renderer_resume(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "resuming", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_resume", "Playing", s.state);
+ }
+
+ /* --- Stop --- */
+
+ reset_callback_info(&c);
+
+ g_debug("stop...");
+ mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "stopping", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state);
+ }
+
+}
+END_TEST
+
+START_TEST(test_playlist_playback)
+{
+ MafwPlaylist *playlist = NULL;
+ gint i = 0;
+ RendererInfo s = {0, };
+ CallbackInfo c = {0, };
+ gchar *cur_item_oid = NULL;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "playlist-changed",
+ G_CALLBACK(playlist_changed_cb),
+ NULL);
+
+ /* --- Create and assign a playlist --- */
+
+ g_debug("assign playlist...");
+ playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
+ cur_item_oid =
+ get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ for (i=0; i<10; i++) {
+ mafw_playlist_insert_item(
+ playlist, i, cur_item_oid, NULL);
+ }
+ g_free(cur_item_oid);
+ cur_item_oid = get_sample_clip_objectid("unexisting.wav");
+ mafw_playlist_insert_item(playlist, 9, cur_item_oid, NULL);
+ g_free(cur_item_oid);
+
+ media_changed_called = FALSE;
+ if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, NULL))
+ {
+ fail("Assign playlist failed");
+ }
+
+ wait_for_state(&s, Stopped, wait_tout_val);
+
+ /* --- Play --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Playing", s.state);
+ }
+
+ /* --- Stop --- */
+
+ reset_callback_info(&c);
+
+ g_debug("stop...");
+ mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "stopping", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_stop", "Stopped", s.state);
+ }
+
+ /* --- Next --- */
+
+ /* Get actual index */
+
+ gint initial_index = s.index;
+
+ for (i=0; i<3; i++) {
+
+ reset_callback_info(&c);
+
+ g_debug("move to next...");
+ mafw_renderer_next(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to next", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Check if the playlist index is correct */
+ fail_if(s.index != initial_index + (i+1), index_err_msg, s.index,
+ initial_index + (i+1));
+ }
+
+
+ /* --- Prev --- */
+
+ /* Get actual index */
+ initial_index = s.index;
+
+ for (i=0; i<3; i++) {
+
+ reset_callback_info(&c);
+
+ g_debug("move to prev...");
+ mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to prev", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Check if the playlist index is correct */
+ fail_if(s.index != initial_index - (i+1), index_err_msg, s.index,
+ initial_index - (i+1));
+ }
+
+ /* Check if renderer remains in Stopped state after some Prev operations */
+ fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state "
+ "after doing prev. The actual state is %s and must be %s",
+ s.state, "Stopped");
+
+ /* --- Stop --- */
+
+ reset_callback_info(&c);
+
+ g_debug("stop...");
+ mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "stopping playback",
+ c.err_code, c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg,"mafw_renderer_stop","Stopped", s.state);
+ }
+
+ /* --- Go to index in Stopped state --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 3...");
+ mafw_renderer_goto_index(g_gst_renderer, 3, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "going to index 3", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Check if the playlist index is correct */
+ fail_if(s.index != 3, index_err_msg, s.index, 3);
+
+ /* Check if renderer remains in Stopped state after running go to index */
+ fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state "
+ "after running go to index. The actual state is %s and must be"
+ " %s", s.state, "Stopped");
+
+ /* --- Play (playlist index is 3) --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Playing", s.state);
+ }
+
+ /* --- Goto index in Playing state --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 5...");
+ mafw_renderer_goto_index(g_gst_renderer, 5, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "going to index", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_goto_index", "Playing", s.state);
+ }
+
+ /* Check if the index if correct */
+ fail_if(s.index != 5, index_err_msg, s.index, 5);
+
+ /* Check if renderer remains in Playing state after running go to index */
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail("Gst renderer didn't remain in Playing state after running "
+ "go to index. The actual state is %s and must be %s",
+ s.state, "Playing");
+ }
+
+ /* --- Goto an invalid index --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto the invalid index 20...");
+ mafw_renderer_goto_index(g_gst_renderer, 20, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error == FALSE)
+ fail("Error not received when we go to an incorrect"
+ "index");
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Check if the previous index (5) remains after an incorrect go to
+ index request */
+ fail_if(s.index != 5, index_err_msg, 5, s.index);
+
+ reset_callback_info(&c);
+
+ /* --- Reassigning playlist --- */
+
+ media_changed_called = FALSE;
+ if (!mafw_renderer_assign_playlist(g_gst_renderer,
+ g_object_ref(playlist), NULL))
+ {
+ fail("Assign playlist failed");
+ }
+
+ wait_for_state(&s, Stopped, wait_tout_val);
+
+ /* --- Go to index with invalid media --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 9...");
+ mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "going to index 9", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Check if the playlist index is correct */
+ fail_if(s.index != 9, index_err_msg, s.index, 9);
+
+ /* Check if renderer remains in Stopped state after running go
+ * to index */
+ fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped "
+ "state after running go to index. The actual state is %d and "
+ "must be %s", s.state, "Stopped");
+
+ /* --- Play (playlist index is 9) --- */
+
+ reset_callback_info(&c);
+
+ c.error_signal_expected = TRUE;
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Transitioning",
+ s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Playing", s.state);
+ }
+
+ fail_if(c.error_signal_received == NULL ||
+ !g_error_matches(c.error_signal_received, MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_INVALID_URI),
+ "No error received or incorrect one");
+
+ if (c.error_signal_received != NULL) {
+ g_error_free(c.error_signal_received);
+ c.error_signal_received = NULL;
+ }
+ c.error_signal_expected = FALSE;
+
+ /* --- Stop --- */
+
+ reset_callback_info(&c);
+
+ g_debug("stop...");
+ mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "stopping playback",
+ c.err_code, c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg,"mafw_renderer_stop","Stopped", s.state);
+ }
+
+ /* --- Remove last media --- */
+
+ mafw_playlist_remove_item(playlist, 10, NULL);
+
+ /* --- Go to index with invalid media --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 9...");
+ mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "going to index 9", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Check if the playlist index is correct */
+ fail_if(s.index != 9, index_err_msg, s.index, 9);
+
+ /* Check if renderer remains in Stopped state after running go
+ * to index */
+ fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped "
+ "state after running go to index. The actual state is %d and "
+ "must be %s", s.state, "Stopped");
+
+ /* --- Play (playlist index is 9) --- */
+
+ reset_callback_info(&c);
+
+ c.error_signal_expected = TRUE;
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Transitioning",
+ s.state);
+ }
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Stopped", s.state);
+ }
+
+ fail_if(c.error_signal_received == NULL ||
+ !g_error_matches(c.error_signal_received, MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_INVALID_URI),
+ "No error received or incorrect one");
+
+ if (c.error_signal_received != NULL) {
+ g_error_free(c.error_signal_received);
+ c.error_signal_received = NULL;
+ }
+ c.error_signal_expected = FALSE;
+
+ /* --- Play incorrect object --- */
+
+ reset_callback_info(&c);
+
+ c.error_signal_expected = TRUE;
+
+ gchar *objectid = get_sample_clip_objectid("unexisting.wav");
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning",
+ s.state);
+ }
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Stopped",
+ s.state);
+ }
+
+ fail_if(c.error_signal_received == NULL ||
+ !g_error_matches(c.error_signal_received, MAFW_RENDERER_ERROR,
+ MAFW_RENDERER_ERROR_INVALID_URI),
+ "No error received or incorrect one");
+
+ if (c.error_signal_received != NULL) {
+ g_error_free(c.error_signal_received);
+ c.error_signal_received = NULL;
+ }
+ c.error_signal_expected = FALSE;
+
+ g_free(objectid);
+
+}
+END_TEST
+
+
+START_TEST(test_repeat_mode_playback)
+{
+ MafwPlaylist *playlist = NULL;
+ gint i = 0;
+ RendererInfo s = {0, };;
+ CallbackInfo c = {0, };;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "playlist-changed",
+ G_CALLBACK(playlist_changed_cb),
+ NULL);
+
+ /* --- Create playlist --- */
+
+ playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
+ for (i=0; i<10; i++) {
+ gchar *cur_item_oid =
+ get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ mafw_playlist_insert_item(
+ playlist, i, cur_item_oid, NULL);
+ g_free(cur_item_oid);
+ }
+
+ /* Set repeat mode */
+ mafw_playlist_set_repeat(playlist, TRUE);
+
+ /* --- Assign playlist --- */
+
+ g_debug("assign playlist...");
+ media_changed_called = FALSE;
+ if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, NULL))
+ {
+ fail("Assign playlist failed");
+ }
+
+ wait_for_state(&s, Stopped, wait_tout_val);
+
+ /* --- Play --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Playing", s.state);
+ }
+
+ /* --- Go to index --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 9...");
+ /* go to the end of the playlist */
+ mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "going to index 9", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* check if the movement was successful */
+ fail_if(s.index != 9, index_err_msg, 9, s.index);
+
+ /* --- Stop --- */
+
+ reset_callback_info(&c);
+
+ g_debug("stop...");
+ mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "stopping playback", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_stop", "Stopped", s.state);
+ }
+
+ /* --- Next --- */
+
+ reset_callback_info(&c);
+
+ g_debug("next...");
+ /* The actual index is 9 */
+ mafw_renderer_next(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to next", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* check if the movement was successful */
+ fail_if(s.index != 0, index_err_msg, s.index, 0);
+
+ /* Check if renderer remains in Stopped state after moving to next */
+ fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state "
+ "after doing next. The actual state is %s and must be %s",
+ s.state, "Stopped");
+
+ /* --- Prev --- */
+
+ reset_callback_info(&c);
+
+ g_debug("prev...");
+ /* The actual index is 0 */
+ mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to prev", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* check if the movement was successful */
+ fail_if(s.index != 9, index_err_msg, s.index, 9);
+
+ /* Check if renderer remains in Stopped state after moving to next */
+ fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state "
+ "after doing next. The actual state is %s and must be %s",
+ s.state, "Stopped");
+}
+END_TEST
+
+
+START_TEST(test_gst_renderer_mode)
+{
+ MafwPlaylist *playlist = NULL;
+ MafwGstRenderer *renderer = NULL;
+ MafwGstRendererPlaybackMode play_mode;
+ gchar *objectid = NULL;
+ gint i = 0;
+ RendererInfo s = {0, };;
+ CallbackInfo c = {0, };;
+ gchar *modes[] = {"MAFW_GST_RENDERER_MODE_PLAYLIST",
+ "MAFW_GST_RENDERER_MODE_STANDALONE"};
+
+ renderer = MAFW_GST_RENDERER(g_gst_renderer);
+
+ /* Initiliaze callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "playlist-changed",
+ G_CALLBACK(playlist_changed_cb),
+ NULL);
+
+ /* --- Create playlist --- */
+
+ playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
+ for (i=0; i<10; i++) {
+ gchar *cur_item_oid =
+ get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ mafw_playlist_insert_item(
+ playlist, i, cur_item_oid, NULL);
+ g_free(cur_item_oid);
+ }
+
+ /* --- Assign playlist --- */
+
+ g_debug("assign playlist...");
+ media_changed_called = FALSE;
+ if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, NULL))
+ {
+ fail("Assign playlist failed");
+ }
+
+ wait_for_state(&s, Stopped, wait_tout_val);
+
+ /* --- Play --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play...");
+
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Transitioning", s.state);
+ }
+
+ /* Check that renderer is playing a playlist */
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Playing", s.state);
+ }
+ play_mode = mafw_gst_renderer_get_playback_mode(renderer);
+ fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST,
+ "Incorrect value of playback_mode: %s", modes[play_mode]);
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ g_debug("play_object... %s",objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
+ g_free(objectid);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Transitioning",
+ s.state);
+ }
+
+ /* Check that renderer is playing an object */
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ play_mode = mafw_gst_renderer_get_playback_mode(renderer);
+ fail_if(play_mode != MAFW_GST_RENDERER_MODE_STANDALONE,
+ "Incorrect value of playback_mode: %s", modes[play_mode]);
+
+ /* Wait EOS_TIMEOUT to ensure that the play_object has finished */
+ wait_until_timeout_finishes(EOS_TIMEOUT);
+
+ /* Check that after playing the object, renderer returns to the playlist
+ playback */
+ play_mode = mafw_gst_renderer_get_playback_mode(renderer);
+ fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST,
+ "Incorrect value of playback_mode: %s", modes[play_mode]);
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
+ g_free(objectid);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Transitioning",
+ s.state);
+ }
+
+ /* Check that renderer is playing an object */
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+ play_mode = mafw_gst_renderer_get_playback_mode(renderer);
+ fail_if(play_mode != MAFW_GST_RENDERER_MODE_STANDALONE,
+ "Incorrect value of playback_mode: %s", modes[play_mode]);
+
+
+ /* --- Move to next when renderer is playing an object --- */
+
+ reset_callback_info(&c);
+
+ g_debug("next...");
+ mafw_renderer_next(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to next", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Check that "next" function finishes the object playback and returns
+ to the playlist playback */
+ play_mode = mafw_gst_renderer_get_playback_mode(renderer);
+ fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST,
+ "Incorrect value of playback_mode: %s", modes[play_mode]);
+
+ /* Check that renderer is still in Playing state */
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ /* --- Stop --- */
+
+ reset_callback_info(&c);
+
+ g_debug("stop...");
+ mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "stopping", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state);
+ }
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Transitioning",
+ s.state);
+ }
+
+ /* Check that renderer is playing an object */
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+ play_mode = mafw_gst_renderer_get_playback_mode(renderer);
+ fail_if(play_mode != MAFW_GST_RENDERER_MODE_STANDALONE,
+ "Incorrect value of playback_mode: %s", modes[play_mode]);
+
+ /* Wait EOS_TIMEOUT to ensure that object playback finishes */
+ wait_until_timeout_finishes(EOS_TIMEOUT);
+
+ /* Check if renderer is in playlist mode and the renderer state is the state before
+ playing the object */
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state);
+ }
+ play_mode = mafw_gst_renderer_get_playback_mode(renderer);
+ fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST,
+ "Incorrect value of playback_mode: %s", modes[play_mode]);
+
+ g_free(objectid);
+}
+END_TEST
+
+#define MOCK_SOURCE(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST((o), \
+ mock_source_get_type(), \
+ MockSource))
+
+typedef struct {
+ MafwSourceClass parent;
+} MockSourceClass;
+
+typedef struct {
+ MafwSource parent;
+
+
+} MockSource;
+
+GType mock_source_get_type(void);
+GObject* mock_source_new(void);
+
+G_DEFINE_TYPE(MockSource, mock_source, MAFW_TYPE_SOURCE);
+
+static GHashTable *get_md_ht; /* Metadata hash-table for the metadata result */
+static GError *get_md_err; /* Error value for the metadata result */
+static gboolean set_mdata_called; /* Whether set_metadata was called or not */
+static gboolean get_mdata_called; /* Whether get_metadata was called or not */
+static gint reference_pcount; /* Reference playcount, what should come in set_metadata */
+static gboolean set_for_playcount; /* TRUE, when the set_metadata is called to modify the playcount */
+static gboolean set_for_lastplayed; /* TRUE, when the set_metadata is called to modify the last-played */
+
+static void get_metadata(MafwSource *self,
+ const gchar *object_id,
+ const gchar *const *metadata,
+ MafwSourceMetadataResultCb callback,
+ gpointer user_data)
+{
+ get_mdata_called = TRUE;
+ fail_if(strcmp(object_id, "mocksource::test"));
+ callback(self, object_id, get_md_ht, user_data, get_md_err);
+}
+
+static void set_metadata(MafwSource *self, const gchar *object_id,
+ GHashTable *metadata,
+ MafwSourceMetadataSetCb callback,
+ gpointer user_data)
+{
+ GValue *curval;
+ gint htsize = 0;
+
+ if (set_for_playcount)
+ htsize++;
+ if (set_for_lastplayed)
+ htsize++;
+ fail_if(strcmp(object_id, "mocksource::test"));
+ fail_if(!metadata);
+ fail_if(g_hash_table_size(metadata) != htsize, "Hash table size: %d vs %d", g_hash_table_size(metadata), htsize);
+ if (set_for_playcount)
+ {
+ curval = mafw_metadata_first(metadata,
+ MAFW_METADATA_KEY_PLAY_COUNT);
+ fail_if(!curval);
+ fail_if(g_value_get_int(curval) != reference_pcount);
+ }
+ if (set_for_lastplayed)
+ {
+ curval = mafw_metadata_first(metadata,
+ MAFW_METADATA_KEY_LAST_PLAYED);
+ fail_if(!curval);
+ fail_if(!G_VALUE_HOLDS(curval, G_TYPE_LONG));
+ }
+ set_mdata_called = TRUE;
+}
+
+static void mock_source_class_init(MockSourceClass *klass)
+{
+ MafwSourceClass *sclass = MAFW_SOURCE_CLASS(klass);
+
+ sclass->get_metadata = get_metadata;
+ sclass->set_metadata = set_metadata;
+
+}
+
+static void mock_source_init(MockSource *source)
+{
+ /* NOP */
+}
+
+GObject* mock_source_new(void)
+{
+ GObject* object;
+ object = g_object_new(mock_source_get_type(),
+ "plugin", "mockland",
+ "uuid", "mocksource",
+ "name", "mocksource",
+ NULL);
+ return object;
+}
+
+
+START_TEST(test_update_stats)
+{
+ MafwGstRenderer *renderer = NULL;
+ MafwSource *src;
+ MafwRegistry *registry;
+
+ registry = MAFW_REGISTRY(mafw_registry_get_instance());
+ fail_if(registry == NULL,
+ "Error: cannot get MAFW registry");
+
+
+ renderer = MAFW_GST_RENDERER(g_gst_renderer);
+ src = MAFW_SOURCE(mock_source_new());
+
+ mafw_registry_add_extension(registry, MAFW_EXTENSION(src));
+
+ /* Error on get_mdata_cb*/
+ set_for_playcount = FALSE;
+ set_for_lastplayed = FALSE;
+ get_md_err = NULL;
+ g_set_error(&get_md_err, MAFW_SOURCE_ERROR,
+ MAFW_SOURCE_ERROR_INVALID_OBJECT_ID,
+ "Wrong object id mocksource::test");
+ renderer->media->object_id = g_strdup("mocksource::test");
+ mafw_gst_renderer_update_stats(renderer);
+ g_error_free(get_md_err);
+ fail_if(set_mdata_called);
+ fail_if(!get_mdata_called);
+
+ /* get_mdata ok, but HashTable is NULL */
+ reference_pcount = 1;
+ get_mdata_called = FALSE;
+ set_for_lastplayed = TRUE;
+ set_for_playcount = TRUE;
+ get_md_err = NULL;
+ mafw_gst_renderer_update_stats(renderer);
+ fail_if(!set_mdata_called);
+ fail_if(!get_mdata_called);
+
+ /* get_mdata ok, but HashTable is empty */
+ get_mdata_called = FALSE;
+ set_mdata_called = FALSE;
+ set_for_lastplayed = TRUE;
+ set_for_playcount = TRUE;
+ get_md_ht = mafw_metadata_new();
+ mafw_gst_renderer_update_stats(renderer);
+ fail_if(!set_mdata_called);
+ fail_if(!get_mdata_called);
+
+ /* get_mdata ok, but HashTable has valid value */
+ get_mdata_called = FALSE;
+ set_mdata_called = FALSE;
+ set_for_lastplayed = TRUE;
+ set_for_playcount = TRUE;
+ mafw_metadata_add_int(get_md_ht,
+ MAFW_METADATA_KEY_PLAY_COUNT,
+ 1);
+ reference_pcount = 2;
+ mafw_gst_renderer_update_stats(renderer);
+ fail_if(!set_mdata_called);
+ fail_if(!get_mdata_called);
+}
+END_TEST
+
+START_TEST(test_play_state)
+{
+ MafwPlaylist *playlist = NULL;
+ gint i = 0;
+ RendererInfo s = {0, };;
+ CallbackInfo c = {0, };;
+ gchar *objectid = NULL;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "playlist-changed",
+ G_CALLBACK(playlist_changed_cb),
+ NULL);
+
+ /* --- Get initial status --- */
+
+ reset_callback_info(&c);
+
+ g_debug("get status...");
+ mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ if (wait_for_state(&s, Stopped, 3000) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Stop",
+ s.state);
+ }
+
+ g_free(objectid);
+
+
+ /* --- Create and assign a playlist --- */
+
+ g_debug("assign playlist...");
+ playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
+ for (i=0; i<10; i++) {
+ gchar *cur_item_oid =
+ get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ mafw_playlist_insert_item(
+ playlist, i, cur_item_oid, NULL);
+ g_free(cur_item_oid);
+ }
+ mafw_playlist_set_repeat(playlist, FALSE);
+
+ media_changed_called = FALSE;
+ if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist,
+ NULL))
+ {
+ fail("Assign playlist failed");
+ }
+
+ wait_for_state(&s, Stopped, wait_tout_val);
+
+ /* --- Play --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail("Play after assigning playlist failed");
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Playing",
+ s.state);
+ }
+
+ /* --- Prev --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to prev...");
+ mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to prev", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(s.index != 9, index_err_msg, s.index, 9);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_prev",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_prev", "Playing",
+ s.state);
+ }
+
+ /* Removing last element */
+
+ g_debug("removing last element...");
+ fail_if(mafw_playlist_get_size(playlist, NULL) != 10,
+ "Playlist should have 10 elements");
+ mafw_playlist_remove_item(playlist, 9, NULL);
+ fail_if(mafw_playlist_get_size(playlist, NULL) != 9,
+ "Playlist should have 9 elements");
+ fail_if(s.index != 8, index_err_msg, s.index, 8);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_playlist_remove_element",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_playlist_remove_element", "Playing",
+ s.state);
+ }
+
+ /* --- Next --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to next...");
+ mafw_renderer_next(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to next", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(s.index != 0, index_err_msg, s.index, 0);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_next",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_next", "Playing",
+ s.state);
+ }
+
+ /* --- Go to index --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 8...");
+ mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "going to index 8", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(s.index != 8, index_err_msg, s.index, 8);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_goto_index",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_goto_index", "Playing",
+ s.state);
+ }
+
+ /* --- Seeking --- */
+
+ reset_callback_info(&c);
+
+ g_debug("seeking...");
+ mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, 1,
+ seek_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "seeking failed", c.err_code,
+ c.err_msg);
+ if (c.seek_position != 1) {
+ fail("seeking failed");
+ }
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Waiting EOS --- */
+
+ if (wait_for_state(&s, Stopped, 2000) == FALSE) {
+ fail(state_err_msg, "EOS", "Stop",
+ s.state);
+ }
+}
+END_TEST
+
+START_TEST(test_pause_state)
+{
+ MafwPlaylist *playlist = NULL;
+ gint i = 0;
+ RendererInfo s = {0, };;
+ CallbackInfo c = {0, };;
+ gchar *objectid = NULL;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "playlist-changed",
+ G_CALLBACK(playlist_changed_cb),
+ NULL);
+
+ /* --- Get initial status --- */
+
+ reset_callback_info(&c);
+
+ g_debug("get status...");
+ mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
+
+ /* --- Create and assign a playlist --- */
+
+ g_debug("assign playlist...");
+ playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
+ for (i=0; i<10; i++) {
+ gchar *cur_item_oid =
+ get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ mafw_playlist_insert_item(
+ playlist, i, cur_item_oid, NULL);
+ g_free(cur_item_oid);
+ }
+ mafw_playlist_set_repeat(playlist, FALSE);
+
+ media_changed_called = FALSE;
+ if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist,
+ NULL))
+ {
+ fail("Assign playlist failed");
+ }
+
+ wait_for_state(&s, Stopped, wait_tout_val);
+
+ /* --- Play --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail("Play failed");
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play",
+ "Transitioning", s.state);
+ }
+
+ /* Testing pause in transitioning */
+
+ reset_callback_info(&c);
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Testing resume in transitioning */
+
+ reset_callback_info(&c);
+
+ g_debug("resume...");
+ mafw_renderer_resume(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "resuming", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ reset_callback_info(&c);
+
+ /* Testing resume without having paused in transitioning */
+
+ reset_callback_info(&c);
+
+ g_debug("resume...");
+ mafw_renderer_resume(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (!c.error)
+ fail(callback_no_err_msg, "resuming", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ reset_callback_info(&c);
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_pause", "Paused",
+ s.state);
+ }
+
+ /* --- Play object in pause --- */
+
+ reset_callback_info(&c);
+
+ objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ reset_callback_info(&c);
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_pause", "Paused",
+ s.state);
+ }
+
+ g_free(objectid);
+
+ /* --- Play --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail("Play failed");
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play",
+ "Transitioning", s.state);
+ }
+
+ reset_callback_info(&c);
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_pause", "Paused",
+ s.state);
+ }
+
+ /* --- Prev --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to prev...");
+ mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to prev", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Check if the playlist index is correct */
+ fail_if(s.index != 9, index_err_msg, s.index, 9);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_prev",
+ "Transitioning", s.state);
+ }
+
+ reset_callback_info(&c);
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_prev", "Playing",
+ s.state);
+ }
+
+ /* Removing last element */
+
+ g_debug("removing last element...");
+ fail_if(mafw_playlist_get_size(playlist, NULL) != 10,
+ "Playlist should have 10 elements");
+ mafw_playlist_remove_item(playlist, 9, NULL);
+ fail_if(mafw_playlist_get_size(playlist, NULL) != 9,
+ "Playlist should have 9 elements");
+ fail_if(s.index != 8, index_err_msg, s.index, 8);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_playlist_remove_item",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_playlist_remove_item", "Playing",
+ s.state);
+ }
+
+ reset_callback_info(&c);
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_playlist_remove_item", "Playing",
+ s.state);
+ }
+
+ /* --- Next --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to next...");
+ mafw_renderer_next(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to next", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Check if the playlist index is correct */
+ fail_if(s.index != 0, index_err_msg, s.index, 0);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_next",
+ "Transitioning", s.state);
+ }
+
+ reset_callback_info(&c);
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_next", "Playing",
+ s.state);
+ }
+
+ /* --- Go to index --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 8...");
+ mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "going to index 8", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* Check if the playlist index is correct */
+ fail_if(s.index != 8, index_err_msg, s.index, 8);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_goto_index",
+ "Transitioning", s.state);
+ }
+
+ reset_callback_info(&c);
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_goto_index", "Playing",
+ s.state);
+ }
+
+ /* --- Seeking --- */
+
+ reset_callback_info(&c);
+
+ mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, 1,
+ seek_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "seeking", c.err_code,
+ c.err_msg);
+ if (c.seek_position != 1) {
+ fail("seeking failed");
+ }
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Stop --- */
+
+ reset_callback_info(&c);
+
+ g_debug("stop...");
+ mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "stopping", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state);
+ }
+}
+END_TEST
+
+START_TEST(test_stop_state)
+{
+ MafwPlaylist *playlist = NULL;
+ gint i = 0;
+ RendererInfo s = {0, };;
+ CallbackInfo c = {0, };;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "playlist-changed",
+ G_CALLBACK(playlist_changed_cb),
+ NULL);
+
+ /* --- Get initial status --- */
+
+ reset_callback_info(&c);
+
+ g_debug("get status...");
+ mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
+
+ /* --- Prev --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to prev...");
+ mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (!c.error)
+ fail(callback_no_err_msg, "moving to prev", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Next --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to next...");
+ mafw_renderer_next(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (!c.error)
+ fail(callback_no_err_msg, "moving to next", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Go to index --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 8...");
+ mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (!c.error)
+ fail(callback_no_err_msg, "going to index 8",
+ c.err_code, c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Create and assign a playlist --- */
+
+ g_debug("assign playlist...");
+ playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
+ for (i=0; i<10; i++) {
+ gchar *cur_item_oid =
+ get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ mafw_playlist_insert_item(
+ playlist, i, cur_item_oid, NULL);
+ g_free(cur_item_oid);
+ }
+ mafw_playlist_set_repeat(playlist, FALSE);
+
+ media_changed_called = FALSE;
+ if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist,
+ NULL))
+ {
+ fail("Assign playlist failed");
+ }
+
+ wait_for_state(&s, Stopped, wait_tout_val);
+
+ /* Removing last element */
+
+ g_debug("removing last element...");
+ fail_if(mafw_playlist_get_size(playlist, NULL) != 10,
+ "Playlist should have 10 elements");
+ mafw_playlist_remove_item(playlist, 9, NULL);
+ fail_if(mafw_playlist_get_size(playlist, NULL) != 9,
+ "Playlist should have 9 elements");
+
+ /* --- Go to index --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 9...");
+ mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (!c.error)
+ fail(callback_no_err_msg, "going to index 9",
+ c.err_code, c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+ reset_callback_info(&c);
+}
+END_TEST
+
+START_TEST(test_transitioning_state)
+{
+ MafwPlaylist *playlist = NULL;
+ gint i = 0;
+ RendererInfo s = {0, };;
+ CallbackInfo c = {0, };;
+ gchar *objectid = NULL;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "playlist-changed",
+ G_CALLBACK(playlist_changed_cb),
+ NULL);
+
+ /* --- Get initial status --- */
+
+ reset_callback_info(&c);
+
+ g_debug("get status...");
+ mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
+
+ /* --- Create and assign a playlist --- */
+
+ g_debug("assign playlist...");
+ playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
+ for (i=0; i<10; i++) {
+ gchar *cur_item_oid =
+ get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ mafw_playlist_insert_item(
+ playlist, i, cur_item_oid, NULL);
+ g_free(cur_item_oid);
+ }
+ mafw_playlist_set_repeat(playlist, FALSE);
+
+ media_changed_called = FALSE;
+ if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist,
+ NULL))
+ {
+ fail("Assign playlist failed");
+ }
+
+ wait_for_state(&s, Stopped, wait_tout_val);
+
+ /* --- Play --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail("Play after assigning playlist failed");
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play",
+ "Transitioning", s.state);
+ }
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ g_free(objectid);
+
+
+ /* --- Prev --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to prev...");
+ mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to prev", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(s.index != 9, index_err_msg, s.index, 9);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_prev",
+ "Transitioning", s.state);
+ }
+
+ /* Removing last element */
+
+ g_debug("removing last element...");
+ fail_if(mafw_playlist_get_size(playlist, NULL) != 10,
+ "Playlist should have 10 elements");
+ mafw_playlist_remove_item(playlist, 9, NULL);
+ fail_if(mafw_playlist_get_size(playlist, NULL) != 9,
+ "Playlist should have 9 elements");
+ fail_if(s.index != 8, index_err_msg, s.index, 8);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_playlist_remove_element",
+ "Transitioning", s.state);
+ }
+
+ /* --- Next --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to next...");
+ mafw_renderer_next(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to next", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(s.index != 0, index_err_msg, s.index, 0);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_next",
+ "Transitioning", s.state);
+ }
+
+ /* --- Go to index --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 8...");
+ mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "going to index 8", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(s.index != 8, index_err_msg, s.index, 8);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_goto_index",
+ "Transitioning", s.state);
+ }
+}
+END_TEST
+
+START_TEST(test_state_class)
+{
+ MafwPlaylist *playlist = NULL;
+ gint i = 0;
+ RendererInfo s = {0, };;
+ CallbackInfo c = {0, };;
+ gchar *objectid = NULL;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "playlist-changed",
+ G_CALLBACK(playlist_changed_cb),
+ NULL);
+
+ /* --- Get initial status --- */
+
+ reset_callback_info(&c);
+
+ g_debug("get status...");
+ mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ /* --- Prev --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to prev...");
+ mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (!c.error)
+ fail(callback_no_err_msg, "moving to prev", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ /* --- Next --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to next...");
+ mafw_renderer_next(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (!c.error)
+ fail(callback_no_err_msg, "moving to next", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ /* --- Go to index --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 8...");
+ mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (!c.error)
+ fail(callback_err_msg, "going to index 8", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Create and assign a playlist --- */
+
+ g_debug("assign playlist...");
+ playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
+ for (i=0; i<10; i++) {
+ gchar *cur_item_oid =
+ get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ mafw_playlist_insert_item(
+ playlist, i, cur_item_oid, NULL);
+ g_free(cur_item_oid);
+ }
+ mafw_playlist_set_repeat(playlist, FALSE);
+
+ media_changed_called = FALSE;
+ if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist,
+ NULL))
+ {
+ fail("Assign playlist failed");
+ }
+
+ wait_for_state(&s, Stopped, wait_tout_val);
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ /* --- Next --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to next...");
+ mafw_renderer_next(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to next", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(s.index != 1, index_err_msg, s.index, 1);
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_next", "Playing",
+ s.state);
+ }
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ /* --- Go to index --- */
+
+ reset_callback_info(&c);
+
+ g_debug("goto index 8...");
+ mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "going to index 8", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(s.index != 8, index_err_msg, s.index, 8);
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_goto_index", "Playing",
+ s.state);
+ }
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ /* --- Prev --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to prev...");
+ mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to prev", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(s.index != 7, index_err_msg, s.index, 7);
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_prev", "Playing",
+ s.state);
+ }
+
+ /* --- Play --- */
+
+ reset_callback_info(&c);
+
+ g_debug("play...");
+ mafw_renderer_play(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail("Play after assigning playlist failed");
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play", "Playing",
+ s.state);
+ }
+
+ /* --- Prev --- */
+
+ reset_callback_info(&c);
+
+ g_debug("move to prev...");
+ mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "moving to prev", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(s.index != 6, index_err_msg, s.index, 6);
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_prev",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_prev",
+ "Transitioning", s.state);
+ }
+
+ /* --- Seeking --- */
+
+ reset_callback_info(&c);
+
+ g_debug("seeking...");
+ mafw_renderer_set_position(g_gst_renderer, SeekRelative, 1,
+ seek_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "seeking failed", c.err_code,
+ c.err_msg);
+ if (c.seek_position != 1) {
+ fail("seeking failed");
+ }
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Seeking --- */
+
+ reset_callback_info(&c);
+
+ g_debug("seeking...");
+ mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, -1,
+ seek_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "seeking failed", c.err_code,
+ c.err_msg);
+ if (c.seek_position != -1) {
+ fail("seeking failed");
+ }
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Seeking --- */
+
+ reset_callback_info(&c);
+
+ g_debug("seeking...");
+ mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, 1,
+ seek_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "seeking failed", c.err_code,
+ c.err_msg);
+ if (c.seek_position != 1) {
+ fail("seeking failed");
+ }
+ } else {
+ fail(no_callback_msg);
+ }
+}
+END_TEST
+
+START_TEST(test_playlist_iterator)
+{
+ MafwPlaylist *playlist = NULL;
+ gint i = 0;
+ CallbackInfo c = {0, };;
+ MafwPlaylistIterator *iterator = NULL;
+ GError *error = NULL;
+ gint size;
+ gint index;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error = FALSE;
+ reset_callback_info(&c);
+
+ /* --- Create and assign a playlist --- */
+
+ g_debug("assign playlist...");
+ playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
+
+ iterator = mafw_playlist_iterator_new();
+ mafw_playlist_iterator_initialize(iterator, playlist, &error);
+ if (error != NULL) {
+ fail("Error found: %s, %d, %s",
+ g_quark_to_string(error->domain),
+ error->code, error->message);
+ }
+
+ for (i = 0; i < 3; i++) {
+ gchar *cur_item_oid = NULL;
+ cur_item_oid =
+ get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ mafw_playlist_insert_item(playlist, 0, cur_item_oid, NULL);
+ g_free(cur_item_oid);
+ }
+
+ size = mafw_playlist_iterator_get_size(iterator, NULL);
+ fail_if(size != 3, "Playlist should have 3 elements and it has %d",
+ size);
+ index = mafw_playlist_iterator_get_current_index(iterator);
+ fail_if(index != 2, "Index should be 2 and it is %d", index);
+
+ mafw_playlist_move_item(playlist, 1, 2, NULL);
+ index = mafw_playlist_iterator_get_current_index(iterator);
+ fail_if(index != 1, "Index should be 1 and it is %d", index);
+
+ mafw_playlist_move_item(playlist, 2, 1, NULL);
+ index = mafw_playlist_iterator_get_current_index(iterator);
+ fail_if(index != 2, "Index should be 2 and it is %d", index);
+
+ mafw_playlist_move_item(playlist, 2, 1, NULL);
+ index = mafw_playlist_iterator_get_current_index(iterator);
+ fail_if(index != 1, "Index should be 1 and it is %d", index);
+
+ mafw_playlist_remove_item(playlist, 0, &error);
+ if (error != NULL) {
+ fail("Error found: %s, %d, %s",
+ g_quark_to_string(error->domain),
+ error->code, error->message);
+ }
+
+ size = mafw_playlist_iterator_get_size(iterator, NULL);
+ fail_if(size != 2, "Playlist should have 2 elements and it has %d",
+ size);
+ index = mafw_playlist_iterator_get_current_index(iterator);
+ fail_if(index != 0, "Index should be 0 and it is %d", index);
+
+ mafw_playlist_iterator_reset(iterator, NULL);
+ index = mafw_playlist_iterator_get_current_index(iterator);
+ fail_if(index != 0, "Index should be 0 and it is %d", index);
+
+ mafw_playlist_remove_item(playlist, 0, &error);
+ if (error != NULL) {
+ fail("Error found: %s, %d, %s",
+ g_quark_to_string(error->domain),
+ error->code, error->message);
+ }
+
+ size = mafw_playlist_iterator_get_size(iterator, NULL);
+ fail_if(size != 1, "Playlist should have 1 elements and it has %d",
+ size);
+ index = mafw_playlist_iterator_get_current_index(iterator);
+ fail_if(index != 0, "Index should be 0 and it is %d", index);
+
+ mafw_playlist_remove_item(playlist, 0, &error);
+ if (error != NULL) {
+ fail("Error found: %s, %d, %s",
+ g_quark_to_string(error->domain),
+ error->code, error->message);
+ }
+
+ size = mafw_playlist_iterator_get_size(iterator, NULL);
+ fail_if(size != 0, "Playlist should have 0 elements and it has %d",
+ size);
+ index = mafw_playlist_iterator_get_current_index(iterator);
+ fail_if(index != -1, "Index should be -1 and it is %d", index);
+
+ g_object_unref(iterator);
+}
+END_TEST
+
+START_TEST(test_video)
+{
+ RendererInfo s = {0, };;
+ CallbackInfo c = {0, };;
+ MetadataChangedInfo m;
+ gchar *objectid = NULL;
+ GstBus *bus = NULL;
+ GstStructure *structure = NULL;
+ GstMessage *message = NULL;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ m.expected_key = NULL;
+ m.value = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "playlist-changed",
+ G_CALLBACK(playlist_changed_cb),
+ NULL);
+ g_signal_connect(g_gst_renderer, "metadata-changed",
+ G_CALLBACK(metadata_changed_cb),
+ &m);
+
+#ifdef HAVE_GDKPIXBUF
+ mafw_extension_set_property_boolean(
+ MAFW_EXTENSION(g_gst_renderer),
+ MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE,
+ TRUE);
+#endif
+
+ /* --- Get initial status --- */
+
+ reset_callback_info(&c);
+
+ g_debug("get status...");
+ mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ objectid = get_sample_clip_objectid(SAMPLE_VIDEO_CLIP);
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ MAFW_GST_RENDERER(g_gst_renderer)->worker->xid = 0x1;
+ bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus;
+ fail_if(bus == NULL, "No GstBus");
+
+ structure = gst_structure_new("prepare-xwindow-id", "width",
+ G_TYPE_INT, 64, "height", G_TYPE_INT, 32,
+ NULL);
+ message = gst_message_new_element(NULL, structure);
+ gst_bus_post(bus, message);
+
+ /* --- Pause --- */
+
+ reset_callback_info(&c);
+
+ m.expected_key = MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI;
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_prev", "Playing",
+ s.state);
+ }
+
+ if (wait_for_metadata(&m, wait_tout_val) == FALSE) {
+ fail("Expected " MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI
+ ", but not received");
+ }
+
+ fail_if(m.value == NULL, "Metadata "
+ MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI " not received");
+
+ g_value_unset(m.value);
+ g_free(m.value);
+ m.value = NULL;
+ m.expected_key = NULL;
+
+ /* --- Resume --- */
+
+ reset_callback_info(&c);
+
+ g_debug("resume...");
+ mafw_renderer_resume(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "resuming", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ /* --- EOS --- */
+
+ if (wait_for_state(&s, Stopped, 3000) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Stop",
+ s.state);
+ }
+
+ g_free(objectid);
+}
+END_TEST
+
+START_TEST(test_media_art)
+{
+ RendererInfo s = {0, };;
+ CallbackInfo c = {0, };;
+ MetadataChangedInfo m;
+ gchar *objectid = NULL;
+ GstBus *bus = NULL;
+ GstMessage *message = NULL;
+ GstTagList *list = NULL;
+ GstBuffer *buffer = NULL;
+ guchar *image = NULL;
+ gchar *image_path = NULL;
+ gsize image_length;
+ GstCaps *caps = NULL;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ m.expected_key = NULL;
+ m.value = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "media-changed",
+ G_CALLBACK(media_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "playlist-changed",
+ G_CALLBACK(playlist_changed_cb),
+ NULL);
+ g_signal_connect(g_gst_renderer, "metadata-changed",
+ G_CALLBACK(metadata_changed_cb),
+ &m);
+
+ /* --- Get initial status --- */
+
+ reset_callback_info(&c);
+
+ g_debug("get status...");
+ mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
+ &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ /* --- Pause --- */
+
+ reset_callback_info(&c);
+
+ g_debug("pause...");
+ mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "pausing", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_prev", "Playing",
+ s.state);
+ }
+
+ /* Emit image */
+
+ bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus;
+ fail_if(bus == NULL, "No GstBus");
+
+ m.expected_key = MAFW_METADATA_KEY_RENDERER_ART_URI;
+
+ image_path = get_sample_clip_path(SAMPLE_IMAGE);
+ fail_if(!g_file_get_contents(image_path + 7, (gchar **) &image,
+ &image_length, NULL),
+ "Could not load test image");
+ g_free(image_path);
+
+ buffer = gst_buffer_new();
+ gst_buffer_set_data(buffer, image, image_length);
+ caps = gst_caps_new_simple("image/png", "image-type",
+ GST_TYPE_TAG_IMAGE_TYPE,
+ GST_TAG_IMAGE_TYPE_FRONT_COVER, NULL);
+ gst_buffer_set_caps(buffer, caps);
+ gst_caps_unref(caps);
+
+ list = gst_tag_list_new();
+ gst_tag_list_add(list, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, buffer,
+ NULL);
+
+ message = gst_message_new_tag(NULL, list);
+ gst_bus_post(bus, message);
+
+ /* --- Resume --- */
+
+ reset_callback_info(&c);
+
+ g_debug("resume...");
+ mafw_renderer_resume(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "resuming", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ if (wait_for_metadata(&m, wait_tout_val) == FALSE) {
+ fail("Expected " MAFW_METADATA_KEY_RENDERER_ART_URI
+ ", but not received");
+ }
+
+ fail_if(m.value == NULL, "Metadata "
+ MAFW_METADATA_KEY_RENDERER_ART_URI " not received");
+
+ g_value_unset(m.value);
+ g_free(m.value);
+ m.value = NULL;
+ m.expected_key = NULL;
+
+ /* --- EOS --- */
+
+ if (wait_for_state(&s, Stopped, 3000) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Stop",
+ s.state);
+ }
+
+ g_free(objectid);
+}
+END_TEST
+
+START_TEST(test_properties_management)
+{
+ RendererInfo s;
+ CallbackInfo c = {0, };;
+ PropertyChangedInfo p;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+ p.expected = NULL;
+ p.received = NULL;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "property-changed",
+ G_CALLBACK(property_changed_cb),
+ &p);
+
+ /* Wait for the volume manager to be initialized */
+
+ /* Volume */
+
+ p.expected = MAFW_PROPERTY_RENDERER_VOLUME;
+
+ if (!wait_for_property(&p, wait_tout_val)) {
+ fail("No property %s received", p.expected);
+ }
+
+ fail_if(p.received == NULL, "No property %s received",
+ p.expected);
+ fail_if(p.received != NULL &&
+ g_value_get_uint(p.received) != 48,
+ "Property with value %d and %d expected",
+ g_value_get_uint(p.received), 48);
+
+ if (p.received != NULL) {
+ g_value_unset(p.received);
+ g_free(p.received);
+ p.received = NULL;
+ }
+ p.expected = NULL;
+
+ /* --- mute --- */
+
+ reset_callback_info(&c);
+
+ c.property_expected = MAFW_PROPERTY_RENDERER_MUTE;
+
+ mafw_extension_set_property_boolean(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, TRUE);
+
+ p.expected = MAFW_PROPERTY_RENDERER_MUTE;
+
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+ if (!wait_for_property(&p, wait_tout_val)) {
+ fail("No property %s received", p.expected);
+ }
+
+ fail_if(p.received == NULL, "No property %s received",
+ p.expected);
+ fail_if(p.received != NULL &&
+ g_value_get_boolean(p.received) != TRUE,
+ "Property with value %d and %d expected",
+ g_value_get_boolean(p.received), TRUE);
+#else
+ if (wait_for_property(&p, wait_tout_val)) {
+ fail("Property %s received and it should not have been",
+ p.expected);
+ }
+
+ fail_if(p.received != NULL,
+ "Property %s received and it should not have been",
+ p.expected);
+#endif
+
+ if (p.received != NULL) {
+ g_value_unset(p.received);
+ g_free(p.received);
+ p.received = NULL;
+ }
+ p.expected = NULL;
+
+ mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, get_property_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "get_property", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(c.property_received == NULL,
+ "No property %s received and expected", c.property_expected);
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+ fail_if(c.property_received != NULL &&
+ g_value_get_boolean(c.property_received) != TRUE,
+ "Property with value %d and %d expected",
+ g_value_get_boolean(c.property_received), TRUE);
+#else
+ fail_if(c.property_received != NULL &&
+ g_value_get_boolean(c.property_received) != FALSE,
+ "Property with value %d and %d expected",
+ g_value_get_boolean(c.property_received), FALSE);
+#endif
+
+ /* --- xid --- */
+
+ reset_callback_info(&c);
+
+ c.property_expected = MAFW_PROPERTY_RENDERER_XID;
+
+ mafw_extension_set_property_uint(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, 50);
+
+ mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, get_property_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "get_property", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(c.property_received == NULL,
+ "No property %s received and expected", c.property_expected);
+ fail_if(c.property_received != NULL &&
+ g_value_get_uint(c.property_received) != 50,
+ "Property with value %d and %d expected",
+ g_value_get_uint(c.property_received), 50);
+
+ /* --- error policy --- */
+
+ reset_callback_info(&c);
+
+ c.property_expected = MAFW_PROPERTY_RENDERER_ERROR_POLICY;
+
+ mafw_extension_set_property_uint(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, 1);
+
+ mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, get_property_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "get_property", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(c.property_received == NULL,
+ "No property %s received and expected", c.property_expected);
+ fail_if(c.property_received != NULL &&
+ g_value_get_uint(c.property_received) != 1,
+ "Property with value %d and %d expected",
+ g_value_get_uint(c.property_received), 1);
+
+ /* --- autopaint --- */
+
+ reset_callback_info(&c);
+
+ c.property_expected = MAFW_PROPERTY_RENDERER_AUTOPAINT;
+
+ mafw_extension_set_property_boolean(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, TRUE);
+
+ mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, get_property_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "get_property", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(c.property_received == NULL,
+ "No property %s received and expected", c.property_expected);
+ fail_if(c.property_received != NULL &&
+ g_value_get_boolean(c.property_received) != TRUE,
+ "Property with value %d and %d expected",
+ g_value_get_boolean(c.property_received), TRUE);
+
+ /* --- colorkey --- */
+
+ reset_callback_info(&c);
+
+ c.property_expected = MAFW_PROPERTY_RENDERER_COLORKEY;
+
+ mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, get_property_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "get_property", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(c.property_received == NULL,
+ "No property %s received and expected", c.property_expected);
+ fail_if(c.property_received != NULL &&
+ g_value_get_int(c.property_received) != -1,
+ "Property with value %d and %d expected",
+ g_value_get_int(c.property_received), -1);
+
+ /* --- current frame on pause --- */
+
+ reset_callback_info(&c);
+
+ c.property_expected = MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE;
+
+ mafw_extension_set_property_boolean(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, TRUE);
+
+ mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, get_property_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "get_property", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(c.property_received == NULL,
+ "No property %s received and expected", c.property_expected);
+ fail_if(c.property_received != NULL &&
+ g_value_get_boolean(c.property_received) != TRUE,
+ "Property with value %d and %d expected",
+ g_value_get_boolean(c.property_received), TRUE);
+
+ /* --- volume --- */
+
+ p.expected = MAFW_PROPERTY_RENDERER_VOLUME;
+
+ mafw_extension_set_property_uint(MAFW_EXTENSION(g_gst_renderer),
+ p.expected, 50);
+
+ if (!wait_for_property(&p, wait_tout_val)) {
+ fail("No property %s received", p.expected);
+ }
+
+ fail_if(p.received == NULL, "No property %s received",
+ p.expected);
+ fail_if(p.received != NULL &&
+ g_value_get_uint(p.received) != 50,
+ "Property with value %d and %d expected",
+ g_value_get_uint(p.received), 50);
+
+ if (p.received != NULL) {
+ g_value_unset(p.received);
+ g_free(p.received);
+ p.received = NULL;
+ }
+ p.expected = NULL;
+
+ c.property_expected = MAFW_PROPERTY_RENDERER_VOLUME;
+
+ mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
+ c.property_expected, get_property_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "get_property", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ fail_if(c.property_received == NULL,
+ "No property %s received and expected", c.property_expected);
+ fail_if(c.property_received != NULL &&
+ g_value_get_uint(c.property_received) != 50,
+ "Property with value %d and %d expected",
+ g_value_get_uint(c.property_received), 50);
+
+#ifndef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME
+ /* Test reconnection to pulse */
+
+ pa_context_disconnect(pa_context_get_instance());
+
+ /* Wait for the volume manager to be reinitialized */
+
+ /* Volume */
+
+ p.expected = MAFW_PROPERTY_RENDERER_VOLUME;
+
+ if (!wait_for_property(&p, wait_tout_val)) {
+ fail("No property %s received", p.expected);
+ }
+
+ fail_if(p.received == NULL, "No property %s received",
+ p.expected);
+ fail_if(p.received != NULL &&
+ g_value_get_uint(p.received) != 48,
+ "Property with value %d and %d expected",
+ g_value_get_uint(p.received), 48);
+
+ if (p.received != NULL) {
+ g_value_unset(p.received);
+ g_free(p.received);
+ p.received = NULL;
+ }
+ p.expected = NULL;
+
+ reset_callback_info(&c);
+#endif
+}
+END_TEST
+
+START_TEST(test_buffering)
+{
+ RendererInfo s;
+ CallbackInfo c;
+ BufferingInfo b;
+ GstBus *bus = NULL;
+ GstMessage *message = NULL;
+
+ /* Initialize callback info */
+ c.err_msg = NULL;
+ c.error_signal_expected = FALSE;
+ c.error_signal_received = NULL;
+ c.property_expected = NULL;
+ c.property_received = NULL;
+ b.requested = FALSE;
+ b.received = FALSE;
+ b.value = 0.0;
+
+ /* Connect to renderer signals */
+ g_signal_connect(g_gst_renderer, "error",
+ G_CALLBACK(error_cb),
+ &c);
+ g_signal_connect(g_gst_renderer, "state-changed",
+ G_CALLBACK(state_changed_cb),
+ &s);
+ g_signal_connect(g_gst_renderer, "buffering-info",
+ G_CALLBACK(buffering_info_cb),
+ &b);
+
+ /* --- Get initial status --- */
+
+ reset_callback_info(&c);
+
+ g_debug("get status...");
+ mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
+
+ /* --- Play object --- */
+
+ reset_callback_info(&c);
+
+ gchar *objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
+ g_debug("play_object... %s", objectid);
+ mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "playing an object", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object",
+ "Transitioning", s.state);
+ }
+
+ if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
+ fail(state_err_msg, "mafw_renderer_play_object", "Playing",
+ s.state);
+ }
+
+ g_free(objectid);
+
+ /* --- Buffering info --- */
+
+ b.requested = TRUE;
+
+ bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus;
+ fail_if(bus == NULL, "No GstBus");
+
+ message = gst_message_new_buffering(NULL, 50);
+ gst_bus_post(bus, message);
+
+ if (wait_for_buffering(&b, wait_tout_val) == FALSE) {
+ fail("Expected buffering message but not received");
+ }
+
+ fail_if(b.value != 0.5, "Expected buffering 0.50 and received %1.2f",
+ b.value);
+
+ b.requested = FALSE;
+ b.received = FALSE;
+ b.value = 0;
+
+ /* --- Buffering info --- */
+
+ b.requested = TRUE;
+
+ message = gst_message_new_buffering(NULL, 100);
+ gst_bus_post(bus, message);
+
+ if (wait_for_buffering(&b, wait_tout_val) == FALSE) {
+ fail("Expected buffering message but not received");
+ }
+
+ fail_if(b.value != 1.0, "Expected buffering 1.00 and received %1.2f",
+ b.value);
+
+ b.requested = FALSE;
+ b.received = FALSE;
+ b.value = 0;
+
+ /* --- Stop --- */
+
+ reset_callback_info(&c);
+
+ g_debug("stop...");
+ mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
+
+ if (wait_for_callback(&c, wait_tout_val)) {
+ if (c.error)
+ fail(callback_err_msg, "stopping", c.err_code,
+ c.err_msg);
+ } else {
+ fail(no_callback_msg);
+ }
+
+ if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
+ fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state);
+ }
+}
+END_TEST
+
+/*----------------------------------------------------------------------------
+ Suit creation
+ ----------------------------------------------------------------------------*/
+
+SRunner * configure_tests(void)
+{
+ SRunner *sr = NULL;
+ Suite *s = NULL;
+ const gchar *tout = g_getenv("WAIT_TIMEOUT");
+
+ if (!tout)
+ wait_tout_val = DEFAULT_WAIT_TOUT;
+ else
+ {
+ wait_tout_val = (gint)strtol(tout, NULL, 0);
+ if (wait_tout_val<=0)
+ wait_tout_val = DEFAULT_WAIT_TOUT;
+ }
+
+ checkmore_wants_dbus();
+ mafw_log_init(":error");
+ /* Create the suite */
+ s = suite_create("MafwGstRenderer");
+
+ /* Create test cases */
+ TCase *tc1 = tcase_create("Playback");
+
+ /* Create unit tests for test case "Playback" */
+ tcase_add_checked_fixture(tc1, fx_setup_dummy_gst_renderer,
+ fx_teardown_dummy_gst_renderer);
+if (1) tcase_add_test(tc1, test_basic_playback);
+if (1) tcase_add_test(tc1, test_playlist_playback);
+if (1) tcase_add_test(tc1, test_repeat_mode_playback);
+if (1) tcase_add_test(tc1, test_gst_renderer_mode);
+if (1) tcase_add_test(tc1, test_update_stats);
+if (1) tcase_add_test(tc1, test_play_state);
+if (1) tcase_add_test(tc1, test_pause_state);
+if (1) tcase_add_test(tc1, test_stop_state);
+if (1) tcase_add_test(tc1, test_transitioning_state);
+if (1) tcase_add_test(tc1, test_state_class);
+if (1) tcase_add_test(tc1, test_playlist_iterator);
+if (1) tcase_add_test(tc1, test_video);
+if (1) tcase_add_test(tc1, test_media_art);
+if (1) tcase_add_test(tc1, test_properties_management);
+if (1) tcase_add_test(tc1, test_buffering);
+
+ tcase_set_timeout(tc1, 0);
+
+ suite_add_tcase(s, tc1);
+
+ /* Create srunner object with the test suite */
+ sr = srunner_create(s);
+
+ return sr;
+}
+
+/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <check.h>
+
+
+/* This must be provided by the test suite implementation */
+SRunner *configure_tests(void);
+
+int main(void)
+{
+ int nf = 0;
+
+ /* Configure test suites to be executed */
+ SRunner *sr = configure_tests();
+
+ /* Run tests */
+ srunner_run_all(sr, CK_ENV);
+
+ /* Retrieve number of failed tests */
+ nf = srunner_ntests_failed(sr);
+
+ /* Free resouces */
+ srunner_free(sr);
+
+ /* Return global success or failure */
+ return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libmafw/mafw-playlist.h>
+#include "mafw-mock-playlist.h"
+
+static GList *pl_list;
+static gchar *pl_name;
+static gboolean pl_rep;
+static gboolean pl_shuffle;
+
+/* Item manipulation */
+
+static gboolean mafw_mock_playlist_insert_item(MafwPlaylist *playlist,
+ guint index,
+ const gchar *objectid,
+ GError **error);
+
+static gboolean mafw_mock_playlist_remove_item(MafwPlaylist *playlist,
+ guint index,
+ GError **error);
+
+static gchar *mafw_mock_playlist_get_item(MafwPlaylist *playlist,
+ guint index, GError **error);
+
+static gboolean mafw_mock_playlist_move_item(MafwPlaylist *playlist,
+ guint from, guint to,
+ GError **error);
+
+static guint mafw_mock_playlist_get_size(MafwPlaylist *playlist,
+ GError **error);
+
+static gboolean mafw_mock_playlist_clear(MafwPlaylist *playlist,
+ GError **error);
+
+static gboolean mafw_mock_playlist_increment_use_count(MafwPlaylist *playlist,
+ GError **error);
+
+static gboolean mafw_mock_playlist_decrement_use_count(MafwPlaylist *playlist,
+ GError **error);
+gboolean mafw_mock_playlist_get_prev(MafwPlaylist *playlist, guint *index,
+ gchar **object_id, GError **error);
+gboolean mafw_mock_playlist_get_next(MafwPlaylist *playlist, guint *index,
+ gchar **object_id, GError **error);
+static void mafw_mock_playlist_get_starting_index(MafwPlaylist *playlist, guint *index,
+ gchar **object_id, GError **error);
+static void mafw_mock_playlist_get_last_index(MafwPlaylist *playlist,
+ guint *index, gchar **object_id,
+ GError **error);
+
+enum {
+ PROP_0,
+ PROP_NAME,
+ PROP_REPEAT,
+ PROP_IS_SHUFFLED,
+};
+
+static void set_prop(MafwMockPlaylist *playlist, guint prop,
+ const GValue *value, GParamSpec *spec)
+{
+ if (prop == PROP_NAME) {
+ pl_name = g_value_dup_string(value);
+ } else if (prop == PROP_REPEAT) {
+ pl_rep = g_value_get_boolean(value);
+ } else
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(playlist, prop, spec);
+}
+
+static void get_prop(MafwMockPlaylist *playlist, guint prop,
+ GValue *value, GParamSpec *spec)
+{
+ if (prop == PROP_NAME) {
+ g_value_take_string(value, pl_name);
+ } else if (prop == PROP_REPEAT) {
+ g_value_set_boolean(value, pl_rep);
+ } else if (prop == PROP_IS_SHUFFLED) {
+ g_value_set_boolean(value, pl_shuffle);
+ } else
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(playlist, prop, spec);
+}
+
+static void mafw_mock_playlist_get_starting_index(MafwPlaylist *playlist, guint *index,
+ gchar **object_id, GError **error)
+{
+ if (g_list_length(pl_list) > 0) {
+ *index = 0;
+ *object_id = g_strdup(g_list_nth_data(pl_list, 0));
+ }
+}
+
+static void mafw_mock_playlist_get_last_index(MafwPlaylist *playlist,
+ guint *index, gchar **object_id,
+ GError **error)
+{
+ *index = g_list_length(pl_list) - 1;
+ *object_id = g_strdup(g_list_nth_data(pl_list, *index));
+}
+
+
+gboolean mafw_mock_playlist_get_next(MafwPlaylist *playlist, guint *index,
+ gchar **object_id, GError **error)
+{
+ gint size;
+ gboolean return_value = TRUE;
+
+ size = g_list_length(pl_list);
+
+ g_return_val_if_fail(size != 0, FALSE);
+
+ if (*index == (size - 1)) {
+ return_value = FALSE;
+ } else {
+ *object_id = g_strdup(g_list_nth_data(pl_list, ++(*index)));
+ }
+
+ return return_value;
+}
+
+gboolean mafw_mock_playlist_get_prev(MafwPlaylist *playlist, guint *index,
+ gchar **object_id, GError **error)
+{
+ gint size;
+ gboolean return_value = TRUE;
+
+ size = g_list_length(pl_list);
+
+ g_return_val_if_fail(size != 0, FALSE);
+
+ if (*index == 0) {
+ return_value = FALSE;
+ } else {
+ *object_id = g_strdup(g_list_nth_data(pl_list, --(*index)));
+ }
+
+ return return_value;
+}
+
+static void playlist_iface_init(MafwPlaylistIface *iface)
+{
+ iface->get_item = mafw_mock_playlist_get_item;
+ iface->insert_item = mafw_mock_playlist_insert_item;
+ iface->clear = mafw_mock_playlist_clear;
+ iface->get_size = mafw_mock_playlist_get_size;
+ iface->remove_item = mafw_mock_playlist_remove_item;
+ iface->move_item = mafw_mock_playlist_move_item;
+ iface->get_starting_index = mafw_mock_playlist_get_starting_index;
+ iface->get_last_index = mafw_mock_playlist_get_last_index;
+ iface->get_next = mafw_mock_playlist_get_next;
+ iface->get_prev = mafw_mock_playlist_get_prev;
+ iface->increment_use_count = mafw_mock_playlist_increment_use_count;
+ iface->decrement_use_count = mafw_mock_playlist_decrement_use_count;
+}
+
+
+static void mafw_mock_playlist_finalize(GObject *object)
+{
+ g_debug(__FUNCTION__);
+
+ while (pl_list)
+ {
+ g_free(pl_list->data);
+ pl_list = g_list_delete_link(pl_list, pl_list);
+ }
+
+}
+
+static void mafw_mock_playlist_class_init(
+ MafwMockPlaylistClass *klass)
+{
+ GObjectClass *oclass = NULL;
+
+ oclass = G_OBJECT_CLASS(klass);
+
+ oclass->set_property = (gpointer)set_prop;
+ oclass->get_property = (gpointer)get_prop;
+ g_object_class_override_property(oclass, PROP_NAME, "name");
+ g_object_class_override_property(oclass, PROP_REPEAT, "repeat");
+ g_object_class_override_property(oclass,
+ PROP_IS_SHUFFLED, "is-shuffled");
+
+ oclass -> finalize = mafw_mock_playlist_finalize;
+}
+
+static void mafw_mock_playlist_init(MafwMockPlaylist *self)
+{
+}
+
+
+
+G_DEFINE_TYPE_WITH_CODE(MafwMockPlaylist, mafw_mock_playlist,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(MAFW_TYPE_PLAYLIST,
+ playlist_iface_init));
+
+
+GObject *mafw_mock_playlist_new(void)
+{
+ MafwMockPlaylist *self;
+
+ self = g_object_new(MAFW_TYPE_MOCK_PLAYLIST, NULL);
+
+ return G_OBJECT(self);
+}
+
+gboolean mafw_mock_playlist_insert_item(MafwPlaylist *self, guint index,
+ const gchar *objectid,
+ GError **error)
+{
+ pl_list = g_list_insert(pl_list, g_strdup(objectid), index);
+
+ g_signal_emit_by_name(self, "contents-changed", index, 0, 1);
+
+ return TRUE;
+}
+
+gboolean mafw_mock_playlist_remove_item(MafwPlaylist *self, guint index,
+ GError **error)
+{
+ GList *element;
+
+ g_return_val_if_fail(g_list_length(pl_list) > 0, FALSE);
+
+ element = g_list_nth(pl_list, index);
+ g_free(element->data);
+ pl_list = g_list_delete_link(pl_list, element);
+
+ g_signal_emit_by_name(self, "contents-changed", index, 1, 0);
+
+ return TRUE;
+}
+
+gchar *mafw_mock_playlist_get_item(MafwPlaylist *self, guint index,
+ GError **error)
+{
+ gchar *oid = g_list_nth_data(pl_list, index);
+
+ if (oid)
+ oid = g_strdup(oid);
+
+ return oid;
+}
+
+guint mafw_mock_playlist_get_size(MafwPlaylist *self, GError **error)
+{
+ return g_list_length(pl_list);
+}
+
+static gboolean mafw_mock_playlist_move_item(MafwPlaylist *playlist,
+ guint from, guint to,
+ GError **error)
+{
+ GList *element_from, *element_to;
+ gpointer data;
+ gint size;
+
+ size = g_list_length(pl_list);
+
+ g_return_val_if_fail(size > 0, FALSE);
+ g_return_val_if_fail(from != to, FALSE);
+ g_return_val_if_fail((from < size) && (to < size), FALSE);
+
+ element_from = g_list_nth(pl_list, from);
+ element_to = g_list_nth(pl_list, to);
+
+ data = element_from->data;
+ element_from->data = element_to->data;
+ element_to->data = data;
+
+ g_signal_emit_by_name(playlist, "item-moved", from, to);
+
+ return TRUE;
+}
+
+static gboolean mafw_mock_playlist_increment_use_count(MafwPlaylist *playlist,
+ GError **error)
+{
+ return TRUE;
+}
+
+static gboolean mafw_mock_playlist_decrement_use_count(MafwPlaylist *playlist,
+ GError **error)
+{
+ return TRUE;
+}
+
+gboolean mafw_mock_playlist_clear(MafwPlaylist *self, GError **error)
+{
+ mafw_mock_playlist_finalize(NULL);
+
+ return TRUE;
+}
+
+/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef MAFW_MOCK_PLAYLIST_H
+#define MAFW_MOCK_PLAYLIST_H
+
+#include <glib-object.h>
+#include <libmafw/mafw-playlist.h>
+#include <libmafw/mafw-errors.h>
+
+/*----------------------------------------------------------------------------
+ GObject type conversion macros
+ ----------------------------------------------------------------------------*/
+
+#define MAFW_TYPE_MOCK_PLAYLIST \
+ (mafw_mock_playlist_get_type())
+
+#define MAFW_MOCK_PLAYLIST(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST(obj, MAFW_TYPE_MOCK_PLAYLIST, \
+ MafwMockPlaylist))
+
+#define MAFW_MOCK_PLAYLIST_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST(klass, MAFW_TYPE_MOCK_PLAYLIST, \
+ MafwMockPlaylistClass))
+
+#define MAFW_IS_MOCK_PLAYLIST(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE(obj, MAFW_TYPE_MOCK_PLAYLIST))
+
+#define MAFW_IS_MOCK_PLAYLIST_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_MOCK_PLAYLIST))
+
+#define MAFW_MOCK_PLAYLIST_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_MOCK_PLAYLIST, \
+ MafwMockPlaylistClass))
+
+/*----------------------------------------------------------------------------
+ GObject type definitions
+ ----------------------------------------------------------------------------*/
+
+typedef struct _MafwMockPlaylist MafwMockPlaylist;
+typedef struct _MafwMockPlaylistClass MafwMockPlaylistClass;
+
+
+struct _MafwMockPlaylist
+{
+ GObject parent_instance;
+
+};
+
+struct _MafwMockPlaylistClass
+{
+ GObjectClass parent_class;
+
+};
+
+/*----------------------------------------------------------------------------
+ Shared playlist-specific functions
+ ----------------------------------------------------------------------------*/
+
+GType mafw_mock_playlist_get_type(void);
+GObject *mafw_mock_playlist_new(void);
+
+#endif
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <glib.h>
+#include "mafw-mock-pulseaudio.h"
+
+typedef void pa_glib_mainloop;
+typedef void pa_mainloop_api;
+typedef void (*pa_context_notify_cb_t)(pa_context *c, void *userdata);
+typedef guint pa_context_flags_t;
+typedef void pa_spawn_api;
+typedef void pa_operation;
+typedef guint32 pa_volume_t;
+typedef struct {
+ guint8 channels;
+ guint map[32];
+} pa_channel_map;
+typedef struct {
+ guint8 channels;
+ pa_volume_t values[32];
+} pa_cvolume;
+typedef struct {
+ const gchar *name;
+ pa_channel_map channel_map;
+ pa_cvolume volume;
+ const char *device;
+ gint mute;
+ gboolean volume_is_absolute;
+} pa_ext_stream_restore_info;
+typedef void (*pa_ext_stream_restore_read_cb_t)(
+ pa_context *c,
+ const pa_ext_stream_restore_info *info, int eol, void *userdata);
+typedef void (*pa_ext_stream_restore_subscribe_cb_t)(pa_context *c,
+ void *userdata);
+typedef void (*pa_context_success_cb_t)(pa_context *c, int success,
+ void *userdata);
+enum pa_context_state {
+ PA_CONTEXT_UNCONNECTED = 0,
+ PA_CONTEXT_CONNECTING,
+ PA_CONTEXT_AUTHORIZING,
+ PA_CONTEXT_SETTING_NAME,
+ PA_CONTEXT_READY,
+ PA_CONTEXT_FAILED,
+ PA_CONTEXT_TERMINATED
+};
+struct _pa_context {
+ pa_context_notify_cb_t state_cb;
+ gpointer state_cb_userdata;
+ enum pa_context_state state;
+ pa_ext_stream_restore_read_cb_t read_cb;
+ gpointer read_cb_userdata;
+ pa_ext_stream_restore_subscribe_cb_t subscribe_cb;
+ gpointer subscribe_cb_userdata;
+ pa_cvolume volume;
+ gboolean mute;
+};
+
+static pa_context *context = NULL;
+
+pa_glib_mainloop *pa_glib_mainloop_new(GMainContext *c);
+char *pa_get_binary_name(char *s, size_t l);
+pa_mainloop_api *pa_glib_mainloop_get_api(pa_glib_mainloop *g);
+pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name);
+void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb,
+ void *userdata);
+int pa_context_connect(pa_context *c, const char *server,
+ pa_context_flags_t flags, const pa_spawn_api *api);
+gint pa_context_get_state(pa_context *c);
+pa_operation *pa_ext_stream_restore2_read(pa_context *c,
+ pa_ext_stream_restore_read_cb_t cb,
+ void *userdata);
+void pa_operation_unref(pa_operation *o);
+pa_volume_t pa_cvolume_max(const pa_cvolume *volume);
+void pa_ext_stream_restore_set_subscribe_cb(
+ pa_context *c,
+ pa_ext_stream_restore_subscribe_cb_t cb, void *userdata);
+gint pa_operation_get_state(pa_operation *o);
+void pa_operation_cancel(pa_operation *o);
+void pa_glib_mainloop_free(pa_glib_mainloop *g);
+pa_cvolume *pa_cvolume_init(pa_cvolume *a);
+pa_cvolume *pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v);
+pa_operation *pa_ext_stream_restore2_write(
+ pa_context *c, gint mode, const pa_ext_stream_restore_info *data[],
+ unsigned n, int apply_immediately, pa_context_success_cb_t cb,
+ void *userdata);
+pa_operation *pa_ext_stream_restore_subscribe(pa_context *c, int enable,
+ pa_context_success_cb_t cb,
+ void *userdata);
+void pa_context_unref(pa_context *c);
+
+pa_glib_mainloop *pa_glib_mainloop_new(GMainContext *c)
+{
+ return (gpointer) 0x1;
+}
+
+char *pa_get_binary_name(char *s, size_t l)
+{
+ g_strlcpy(s, "mafw-gst-renderer-tests", l);
+
+ return NULL;
+}
+
+pa_mainloop_api *pa_glib_mainloop_get_api(pa_glib_mainloop *g)
+{
+ return (gpointer) 0x1;
+}
+
+pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name)
+{
+ pa_context *c = g_new0(pa_context, 1);
+
+ pa_cvolume_set(&c->volume, 1, 32000);
+
+ context = c;
+
+ return c;
+}
+
+void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb,
+ void *userdata)
+{
+ c->state_cb = cb;
+ c->state_cb_userdata = userdata;
+}
+
+static gboolean _pa_context_connect_idle(gpointer userdata)
+{
+ pa_context *c = userdata;
+ c->state++;
+ if (c->state_cb != NULL) {
+ c->state_cb(c, c->state_cb_userdata);
+ }
+ return c->state != PA_CONTEXT_READY;
+}
+
+int pa_context_connect(pa_context *c, const char *server,
+ pa_context_flags_t flags, const pa_spawn_api *api)
+{
+ g_idle_add(_pa_context_connect_idle, c);
+ return 1;
+}
+
+gint pa_context_get_state(pa_context *c)
+{
+ return c->state;
+}
+
+static gboolean _pa_ext_stream_restore2_read_idle(gpointer userdata)
+{
+ pa_context *c = userdata;
+ pa_ext_stream_restore_info info = { 0, };
+
+ info.name = "sink-input-by-media-role:x-maemo";
+ pa_cvolume_set(&info.volume, 1, c->volume.values[0]);
+ info.mute = c->mute;
+
+ c->read_cb(c, &info, 1, c->read_cb_userdata);
+
+ return FALSE;
+}
+
+pa_operation *pa_ext_stream_restore2_read(pa_context *c,
+ pa_ext_stream_restore_read_cb_t cb,
+ void *userdata)
+{
+ c->read_cb = cb;
+ c->read_cb_userdata = userdata;
+ g_idle_add(_pa_ext_stream_restore2_read_idle, c);
+ return (gpointer) 0x1;
+}
+
+void pa_operation_unref(pa_operation *o)
+{
+}
+
+pa_volume_t pa_cvolume_max(const pa_cvolume *volume)
+{
+ return volume->values[0];
+}
+
+pa_operation *pa_ext_stream_restore_subscribe(pa_context *c, int enable,
+ pa_context_success_cb_t cb,
+ void *userdata)
+{
+ if (cb != NULL) {
+ cb(c, TRUE, userdata);
+ }
+ return (gpointer) 0x1;
+}
+
+void pa_ext_stream_restore_set_subscribe_cb(
+ pa_context *c,
+ pa_ext_stream_restore_subscribe_cb_t cb, void *userdata)
+{
+ c->subscribe_cb = cb;
+ c->subscribe_cb_userdata = userdata;
+}
+
+gint pa_operation_get_state(pa_operation *o)
+{
+ return 1;
+}
+
+void pa_operation_cancel(pa_operation *o)
+{
+}
+
+void pa_context_unref(pa_context *c)
+{
+ g_free(c);
+}
+
+void pa_glib_mainloop_free(pa_glib_mainloop *g)
+{
+}
+
+pa_cvolume *pa_cvolume_init(pa_cvolume *a)
+{
+ pa_cvolume_set(a, 1, 0);
+ return a;
+}
+
+pa_cvolume *pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v)
+{
+ a->channels = 1;
+ a->values[0] = v;
+ return a;
+}
+
+static gboolean _pa_ext_stream_restore_write_idle(gpointer userdata)
+{
+ pa_context *c = userdata;
+
+ if (c->subscribe_cb != NULL) {
+ c->subscribe_cb(c, c->subscribe_cb_userdata);
+ }
+
+ return FALSE;
+}
+
+pa_operation *pa_ext_stream_restore2_write(
+ pa_context *c, gint mode, const pa_ext_stream_restore_info *data[],
+ unsigned n, int apply_immediately, pa_context_success_cb_t cb,
+ void *userdata)
+{
+ const pa_ext_stream_restore_info *info = data[0];
+
+ pa_cvolume_set(&c->volume, 1, info->volume.values[0]);
+ c->mute = info->mute;
+
+ g_idle_add(_pa_ext_stream_restore_write_idle, c);
+
+ return (gpointer) 0x1;
+}
+
+static gboolean _pa_context_disconnect_idle(gpointer userdata)
+{
+ pa_context *c = userdata;
+ c->state = PA_CONTEXT_TERMINATED;
+ if (c->state_cb != NULL) {
+ c->state_cb(c, c->state_cb_userdata);
+ }
+ return FALSE;
+}
+
+void pa_context_disconnect(pa_context *c)
+{
+ g_idle_add(_pa_context_disconnect_idle, c);
+}
+
+pa_context *pa_context_get_instance(void)
+{
+ return context;
+}
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef MAFW_MOCK_PULSEAUDIO_H
+#define MAFW_MOCK_PULSEAUDIO_H
+
+typedef struct _pa_context pa_context;
+
+void pa_context_disconnect(pa_context *c);
+pa_context *pa_context_get_instance(void);
+
+#endif
--- /dev/null
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * test.c
+ *
+ * Test of the playback system
+ *
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <termios.h>
+
+#include "mafw-gst-renderer.h"
+#include <libmafw/mafw-metadata.h>
+#include <libmafw/mafw-registry.h>
+
+MafwGstRenderer *gst_renderer;
+GMainLoop *loop;
+static struct termios tio_orig;
+guint seek_delta = 2;
+gfloat volume = 0.7;
+gboolean muted = FALSE;
+
+
+/**
+ *@time: how long to wait, in microsecs
+ *
+ */
+int kbhit (int time) {
+ fd_set rfds;
+ struct timeval tv;
+ int retval;
+ char c;
+
+ FD_ZERO (&rfds);
+ FD_SET (0, &rfds);
+
+ /* Wait up to 'time' microseconds. */
+ tv.tv_sec=time / 1000;
+ tv.tv_usec = (time % 1000)*1000;
+
+ retval=select (1, &rfds, NULL, NULL, &tv);
+ if(retval < 1) return -1;
+ retval = read (0, &c, 1);
+ if (retval < 1) return -1;
+ return (int) c;
+}
+
+
+/**
+ *
+ *
+ */
+static void raw_kb_enable (void) {
+ struct termios tio_new;
+ tcgetattr(0, &tio_orig);
+
+ tio_new = tio_orig;
+ tio_new.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
+ tio_new.c_cc[VMIN] = 1;
+ tio_new.c_cc[VTIME] = 0;
+ tcsetattr (0, TCSANOW, &tio_new);
+}
+
+static void raw_kb_disable (void)
+{
+ tcsetattr (0,TCSANOW, &tio_orig);
+}
+
+static void get_position_cb(MafwRenderer* self, gint position, gpointer user_data,
+ const GError* error)
+{
+ guint* rpos = (guint*) user_data;
+ g_return_if_fail(rpos != NULL);
+
+ *rpos = position;
+}
+
+/**
+ *
+ *
+ */
+static gboolean idle_cb (gpointer data)
+{
+ gboolean ret = TRUE;
+ GError *error = NULL;
+
+ int c = kbhit (0);
+ if (c == -1) {
+ usleep (10 * 1000);
+ return TRUE;
+ }
+
+ printf ("c = %d\n", c);
+ /* '.' key */
+ if (c == 46) {
+ printf ("Seeking %d seconds forward\n", seek_delta);
+ gint pos = 0;
+
+ mafw_gst_renderer_get_position(MAFW_RENDERER(gst_renderer),
+ get_position_cb, &pos);
+
+ printf (" Position before seek: %d\n", pos);
+ pos += seek_delta;
+ mafw_gst_renderer_set_position(MAFW_RENDERER(gst_renderer), pos,
+ NULL, NULL);
+
+ mafw_gst_renderer_get_position(MAFW_RENDERER(gst_renderer),
+ get_position_cb, &pos);
+
+ printf (" Position after seek: %d\n", pos);
+ }
+ /* ',' key */
+ else if (c == 44) {
+ printf ("Seeking %d seconds backwards\n", seek_delta);
+ gint pos = 0;
+
+ mafw_gst_renderer_get_position(MAFW_RENDERER(gst_renderer),
+ get_position_cb, &pos);
+
+ printf (" Position before seek: %d\n", pos);
+ pos -= seek_delta;
+ mafw_gst_renderer_set_position(MAFW_RENDERER(gst_renderer), pos,
+ NULL, NULL);
+
+ mafw_gst_renderer_get_position(MAFW_RENDERER(gst_renderer),
+ get_position_cb, &pos);
+
+ printf (" Position after seek: %d\n", pos);
+ }
+ /* '' (space) key */
+ else if (c == 32) {
+ if (gst_renderer->current_state == Playing) {
+ printf ("Pausing...\n");
+ mafw_gst_renderer_pause(MAFW_RENDERER (gst_renderer), NULL, NULL);
+ }
+ else if (gst_renderer->current_state == Paused) {
+ printf ("Resuming...\n");
+ mafw_gst_renderer_resume(MAFW_RENDERER (gst_renderer), NULL, NULL);
+ }
+ }
+ /* 'p' key */
+ else if (c == 112) {
+ printf ("Playing...\n");
+ mafw_gst_renderer_play (MAFW_RENDERER (gst_renderer), NULL, NULL);
+ }
+ /* 's' key */
+ else if (c == 115) {
+ printf ("Stopping\n");
+ mafw_gst_renderer_stop (MAFW_RENDERER (gst_renderer), NULL, NULL);
+ }
+ /* 'g' key */
+ else if (c == 103) {
+ printf ("Getting position\n");
+ gint pos = 0;
+
+ mafw_gst_renderer_get_position(MAFW_RENDERER(gst_renderer),
+ get_position_cb, &pos);
+
+ printf ("Current position: %d\n", pos);
+ }
+ /* '+' key */
+ else if (c == 43) {
+ volume += 0.1;
+ printf ("Increasing volume to %lf\n", volume);
+ mafw_extension_set_property_float(MAFW_EXTENSION(gst_renderer),
+ "volume", volume);
+ }
+ /* '-' key */
+ else if (c == 45) {
+ volume -= 0.1;
+ printf ("Decreasing volume to %lf\n", volume);
+ mafw_extension_set_property_float(MAFW_EXTENSION(gst_renderer),
+ "volume", volume);
+ }
+ /* 'm' key */
+ else if (c == 109) {
+ muted = !muted;
+ printf ("(Un)Muting...\n");
+ mafw_extension_set_property_boolean(MAFW_EXTENSION(gst_renderer),
+ "mute", muted);
+ }
+ /* '?' key */
+ else if (c == 63) {
+ printf ("COMMANDS:\n" \
+ " s\t\tStop\n" \
+ " p\t\tPlay\n" \
+ " space\tPause/Resume\n" \
+ " +\t\tVolume up\n" \
+ " -\t\tVolume down\n" \
+ " m\t\tMute/Unmute\n" \
+ " .\t\tSeek forward 2 sec\n" \
+ " ,\t\tSeek backwards 2 sec\n" \
+ " q\t\tQuit\n");
+ }
+ /* 'q' key */
+ else if (c == 113) {
+ printf ("QUIT\n");
+ mafw_gst_renderer_stop (MAFW_RENDERER (gst_renderer), NULL, NULL);
+ raw_kb_disable ();
+ g_main_loop_quit (loop);
+ ret = FALSE;
+ }
+ if (error) {
+ printf ("Error occured during the operation\n");
+ g_error_free (error);
+ }
+ return ret;
+}
+
+
+/**
+ *
+ *
+ */
+static void metadata_changed (MafwGstRenderer *gst_renderer,
+ GHashTable *metadata,
+ gpointer user_data)
+{
+ g_print("Metadata changed:\n");
+ mafw_metadata_print (metadata, NULL);
+}
+
+
+/**
+ *
+ *
+ */
+static void buffering_cb (MafwGstRenderer *gst_renderer,
+ gfloat percentage,
+ gpointer user_data)
+{
+ g_print("Buffering: %f\n", percentage);
+}
+
+static void play_uri_cb(MafwRenderer* renderer, gpointer user_data, const GError* error)
+{
+ if (error != NULL) {
+ printf("Unable to play: %s\n", error->message);
+ exit(1);
+ }
+}
+
+/**
+ *
+ *
+ */
+gint main(gint argc, gchar ** argv)
+{
+ MafwRegistry *registry;
+
+ g_type_init();
+ gst_init (&argc, &argv);
+
+ if (argc != 2) {
+ g_print("Usage: mafw-test-player <media-uri>\n");
+ exit(1);
+ }
+
+ raw_kb_enable();
+
+ registry = MAFW_REGISTRY(mafw_registry_get_instance());
+ gst_renderer = MAFW_GST_RENDERER(mafw_gst_renderer_new(registry));
+ g_signal_connect (G_OBJECT (gst_renderer),
+ "metadata_changed",
+ G_CALLBACK (metadata_changed),
+ gst_renderer);
+
+ g_signal_connect (G_OBJECT (gst_renderer),
+ "buffering_info",
+ G_CALLBACK (buffering_cb),
+ gst_renderer);
+
+ mafw_renderer_play_uri(MAFW_RENDERER (gst_renderer), argv[1], play_uri_cb,
+ NULL);
+
+ loop = mafw_gst_renderer_get_loop(gst_renderer);
+
+ g_idle_add (idle_cb, NULL);
+ g_main_loop_run (loop);
+
+ g_object_unref (G_OBJECT (gst_renderer));
+ return 0;
+}
--- /dev/null
+{
+ <1>
+ Memcheck:Leak
+ fun:malloc
+ fun:g_malloc
+ fun:g_slice_alloc
+ fun:g_slice_alloc0
+ fun:g_type_create_instance
+ fun:g_object_constructor
+ fun:g_object_newv
+ fun:g_object_new_valist
+ fun:g_object_new
+ fun:gst_element_factory_create
+ fun:gst_element_make_from_uri
+ obj:*
+ obj:*
+ obj:*
+ fun:gst_element_change_state
+ fun:gst_element_continue_state
+ fun:gst_element_change_state
+ obj:*
+ fun:gst_element_set_state
+ fun:_construct_pipeline
+}
+{
+ <2>
+ Memcheck:Leak
+ fun:malloc
+ fun:g_malloc
+ fun:g_slice_alloc
+ fun:g_slice_alloc0
+ fun:g_type_create_instance
+ fun:g_object_constructor
+ fun:g_object_newv
+ fun:g_object_new_valist
+ fun:g_object_new
+ fun:gst_pad_new_from_template
+ obj:*
+ fun:g_type_create_instance
+ fun:g_object_constructor
+ fun:g_object_newv
+ fun:g_object_new_valist
+ fun:g_object_new
+ fun:gst_element_factory_create
+ fun:gst_element_make_from_uri
+ obj:*
+ obj:*
+}
+{
+ <3>
+ Memcheck:Cond
+ fun:_dl_relocate_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:do_dlopen
+ fun:_dl_catch_error
+ fun:dlerror_run
+ fun:__libc_dlopen_mode
+ fun:__nss_lookup_function
+ fun:__nss_lookup
+ fun:__nss_passwd_lookup
+ fun:getpwnam_r@@GLIBC_2.1.2
+}
+{
+ <4>
+ Memcheck:Leak
+ fun:realloc
+ fun:g_realloc
+ obj:*
+ fun:g_signal_newv
+ fun:g_signal_new_valist
+ fun:g_signal_new
+ obj:*
+ fun:g_type_class_ref
+ fun:g_type_class_ref
+ fun:g_object_newv
+ fun:g_object_new_valist
+ fun:g_object_new
+}
+
+{
+ <5>
+ Memcheck:Leak
+ fun:calloc
+ fun:g_malloc0
+ obj:*
+ fun:g_type_create_instance
+ obj:*
+ fun:g_object_newv
+ fun:g_object_new_valist
+ fun:g_object_new
+ fun:gst_element_factory_create
+ fun:gst_element_make_from_uri
+ obj:*
+ obj:*
+}
+
+{
+ <6>
+ Memcheck:Leak
+ fun:vasprintf
+ fun:g_vasprintf
+ fun:g_strdup_vprintf
+ fun:g_strdup_printf
+ fun:gst_uri_construct
+ fun:g_object_newv
+ obj:*
+ obj:*
+ fun:gst_uri_handler_set_uri
+ fun:gst_element_make_from_uri
+ obj:*
+ obj:*
+}
+{
+ <7>
+ Memcheck:Leak
+ fun:malloc
+ fun:open_path
+ fun:_dl_map_object
+ fun:openaux
+ fun:_dl_catch_error
+ fun:_dl_map_object_deps
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+}
+{
+ <8>
+ Memcheck:Leak
+ fun:malloc
+ fun:expand_dynamic_string_token
+ fun:_dl_map_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.1
+ fun:g_module_open
+ fun:gst_plugin_load_file
+}
+{
+ <9>
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_new_object
+ fun:_dl_map_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.1
+ fun:g_module_open
+}
+{
+ <10>
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_map_object_deps
+ fun:_dl_map_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.1
+ fun:g_module_open
+ fun:gst_plugin_load_file
+ fun:gst_plugin_load_by_name
+}
+{
+ <11>
+ Memcheck:Leak
+ fun:calloc
+ fun:_dl_check_map_versions
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.1
+ fun:g_module_open
+ fun:gst_plugin_load_file
+ fun:gst_plugin_load_by_name
+}
+{
+ <12>
+ Memcheck:Leak
+ fun:malloc
+ fun:g_malloc0
+ obj:*
+ obj:*
+ fun:g_type_create_instance
+ obj:*
+ fun:g_object_newv
+ fun:g_object_new_valist
+ fun:g_object_new
+ fun:gst_element_factory_create
+ fun:gst_element_make_from_uri
+ obj:*
+ obj:*
+}
+{
+ <13>
+ Memcheck:Leak
+ fun:malloc
+ fun:realloc
+ fun:g_realloc
+ obj:*
+ fun:g_array_sized_new
+ obj:*
+ fun:gst_structure_copy
+ fun:gst_caps_copy
+ fun:gst_audio_filter_class_add_pad_templates
+ obj:*
+ fun:g_type_class_ref
+ fun:gst_element_register
+}
+{
+ <14>
+ Memcheck:Cond
+ fun:strlen
+ fun:_dl_init_paths
+ fun:dl_main
+ fun:_dl_sysdep_start
+ fun:_dl_start
+}
+{
+ <15>
+ Memcheck:Cond
+ fun:_dl_relocate_object
+ fun:dl_main
+ fun:_dl_sysdep_start
+ fun:_dl_start
+}
+{
+ <15>
+ Memcheck:Leak
+ fun:calloc
+ fun:allocate_dtv
+ fun:_dl_allocate_tls
+ fun:pthread_create@@GLIBC_2.1
+ obj:*
+ fun:g_thread_create_full
+ obj:*
+ fun:g_thread_pool_push
+ fun:gst_task_start
+ fun:gst_pad_start_task
+ obj:*
+ fun:gst_pad_activate_pull
+}
+{
+ <16>
+ Memcheck:Cond
+ fun:_dl_relocate_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.1
+ fun:g_module_open
+ fun:gst_plugin_load_file
+ fun:gst_plugin_load_by_name
+ fun:gst_plugin_feature_load
+}
+{
+ <17>
+ Memcheck:Leak
+ fun:malloc
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.1
+ fun:g_module_open
+ fun:gst_plugin_load_file
+ fun:gst_plugin_load_by_name
+ fun:gst_plugin_feature_load
+}
+{
+ <17>
+ Memcheck:Leak
+ fun:realloc
+ fun:vasprintf
+ fun:g_vasprintf
+ fun:g_strdup_vprintf
+ fun:g_strdup_printf
+ fun:gst_uri_construct
+ fun:gst_file_src_set_location
+ fun:gst_file_src_uri_set_uri
+ fun:gst_uri_handler_set_uri
+ fun:gst_element_make_from_uri
+ obj:*
+ obj:*
+}
+{
+ <18>
+ Memcheck:Leak
+ fun:calloc
+ fun:parse_bracket_exp
+ fun:parse_expression
+ fun:parse_branch
+ fun:parse_reg_exp
+ fun:parse_expression
+ fun:parse_branch
+ fun:parse_reg_exp
+ fun:parse_expression
+ fun:parse_branch
+ fun:parse_reg_exp
+ fun:re_compile_internal
+}
+{
+ <19>
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_map_object_deps
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.1
+ fun:g_module_open
+ fun:gst_plugin_load_file
+ fun:gst_plugin_load_by_name
+}
+{
+ <20>
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_new_object
+ fun:_dl_map_object_from_fd
+ fun:_dl_map_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.1
+ fun:g_module_open
+}
+{
+ <21>
+ Memcheck:Leak
+ fun:malloc
+ fun:g_malloc
+ obj:*
+ obj:*
+ fun:g_type_create_instance
+ obj:*
+ fun:g_object_newv
+ fun:g_object_new_valist
+ fun:g_object_new
+ fun:gst_element_factory_create
+ fun:gst_element_make_from_uri
+ obj:*
+}
+{
+ <22>
+ Memcheck:Leak
+ fun:calloc
+ fun:dbus_malloc0
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+ fun:dbus_parse_address
+ obj:*
+ fun:dbus_connection_open
+ obj:*
+ fun:dbus_bus_get
+ obj:*
+}
+{
+ <23>
+ Memcheck:Leak
+ fun:realloc
+ fun:g_realloc
+ obj:*
+ fun:g_array_append_vals
+ obj:*
+ fun:gst_structure_set_valist
+ fun:gst_caps_set_simple
+ fun:gst_riff_create_audio_caps
+ fun:gst_riff_create_audio_template_caps
+ obj:*
+ fun:g_type_class_ref
+ fun:gst_element_register
+}
+{
+ <24>
+ Memcheck:Leak
+ fun:realloc
+ fun:dbus_realloc
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+}
+{
+ <25>
+ Memcheck:Leak
+ fun:calloc
+ fun:_dl_new_object
+ fun:_dl_map_object_from_fd
+ fun:_dl_map_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.1
+ fun:g_module_open
+}
+{
+ <26>
+ Memcheck:Leak
+ fun:realloc
+ fun:vasprintf
+ fun:g_vasprintf
+ fun:g_strdup_vprintf
+ fun:g_strdup_printf
+ fun:gst_uri_construct
+ obj:*
+ obj:*
+ fun:gst_uri_handler_set_uri
+ fun:gst_element_make_from_uri
+ obj:*
+ obj:*
+}
+{
+ <27>
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_new_object
+ fun:_dl_map_object_from_fd
+ fun:_dl_map_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+ fun:_dl_open
+ fun:dlopen_doit
+ fun:_dl_catch_error
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.1
+ fun:g_module_open
+}
+{
+ <28>
+ Memcheck:Leak
+ fun:realloc
+ fun:vasprintf
+ fun:g_vasprintf
+ fun:g_strdup_vprintf
+ fun:g_strdup_printf
+ fun:gst_uri_construct
+ obj:*
+ obj:*
+ fun:gst_uri_handler_set_uri
+ fun:gst_element_make_from_uri
+ obj:*
+ obj:*
+}
+{
+ <29>
+ Memcheck:Leak
+ fun:malloc
+ fun:g_malloc
+ fun:g_strdup
+ fun:gst_object_set_name
+ fun:gst_element_factory_create
+ fun:gst_element_make_from_uri
+ obj:*
+ obj:*
+ obj:*
+ fun:gst_element_change_state
+ fun:gst_element_continue_state
+ fun:gst_element_change_state
+}
+{
+ <30>
+ Memcheck:Cond
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+}
+{
+ <31>
+ Memcheck:Cond
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+}
+{
+ <32>
+ Memcheck:Cond
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ fun:__libc_dlopen_mode
+ fun:__nss_lookup_function
+ obj:/targets/*/lib/libc-2.5.so
+ fun:__nss_passwd_lookup
+ fun:getpwnam_r
+ obj:/targets/*/usr/lib/libglib-2.0.so.0.1800.1
+}
+{
+ <33>
+ Memcheck:Cond
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ fun:__libc_dlopen_mode
+ fun:__nss_lookup_function
+ obj:/targets/*/lib/libc-2.5.so
+ fun:__nss_passwd_lookup
+ fun:getpwnam_r
+ obj:/targets/*/usr/lib/libglib-2.0.so.0.1800.1
+}
+{
+ <34>
+ Memcheck:Leak
+ fun:calloc
+ fun:g_malloc0
+ obj:/targets/*/usr/lib/libgobject-2.0.so.0.1800.1
+ obj:/targets/*/usr/lib/libgobject-2.0.so.0.1800.1
+ fun:g_type_init_with_debug_flags
+ fun:g_type_init
+ fun:fx_setup_dummy_gst_renderer
+ fun:tcase_run_checked_setup
+ fun:srunner_run_all
+ fun:main
+}
+{
+ <35>
+ Memcheck:Leak
+ fun:calloc
+ fun:g_malloc0
+ obj:/targets/*/usr/lib/libglib-2.0.so.0.1800.1
+ fun:g_slice_alloc
+ fun:g_slist_prepend
+ fun:g_strsplit
+ fun:mafw_log_init
+ fun:configure_tests
+ fun:main
+}
+{
+ <36>
+ Memcheck:Addr4
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libdl-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libdl-2.5.so
+}
+{
+ <37>
+ Memcheck:Leak
+ fun:*
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ fun:reg*
+ fun:mafw_source_create_objectid
+ fun:get_sample_clip_objectid
+ fun:*
+ fun:srunner_run_all
+ fun:main
+}
+{
+ <38>
+ Memcheck:Leak
+ fun:*
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+}
+{
+ <39>
+ Memcheck:Leak
+ fun:*
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ fun:reg*
+ fun:mafw_source_create_objectid
+ fun:get_sample_clip_objectid
+ fun:*
+ fun:srunner_run_all
+ fun:main
+}
+{
+ <40>
+ Memcheck:Leak
+ fun:*
+ obj:/targets/*/lib/libc-2.5.so
+ fun:reg*
+ fun:mafw_source_create_objectid
+ fun:get_sample_clip_objectid
+ fun:*
+ fun:srunner_run_all
+ fun:main
+}
+{
+ <41>
+ Memcheck:Leak
+ fun:*
+ fun:reg*
+ fun:mafw_source_create_objectid
+ fun:get_sample_clip_objectid
+ fun:*
+ fun:srunner_run_all
+ fun:main
+}
+{
+ <42>
+ Memcheck:Leak
+ fun:realloc
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ fun:regcomp
+ fun:mafw_source_create_objectid
+ fun:get_sample_clip_objectid
+ fun:*
+ fun:srunner_run_all
+}
+{
+ <43>
+ Memcheck:Cond
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ fun:__libc_dlopen_mode
+ fun:__nss_lookup_function
+ obj:/targets/*/lib/libc-2.5.so
+ fun:__nss_passwd_lookup
+ fun:getpwnam_r
+}
+{
+ <44>
+ Memcheck:Addr4
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ fun:__libc_dlopen_mode
+ fun:__nss_lookup_function
+ obj:/targets/*/lib/libc-2.5.so
+}
+{
+ <45>
+ Memcheck:Leak
+ fun:malloc
+ fun:fdopen
+ fun:tmpfile
+ fun:setup_pipe
+ fun:srunner_run_all
+ fun:main
+}
+{
+ <46>
+ Memcheck:Leak
+ fun:realloc
+ fun:erealloc
+ fun:maybe_grow
+ fun:list_add_end
+ fun:_tcase_add_test
+ fun:configure_tests
+ fun:main
+}
+{
+ <47>
+ Memcheck:Leak
+ fun:malloc
+ fun:realloc
+ fun:g_realloc
+ obj:/targets/*/usr/lib/libgobject-2.0.so.0.1800.1
+ fun:g_type_register_static
+ fun:g_type_plugin_get_type
+ fun:g_type_init_with_debug_flags
+ fun:g_type_init
+ fun:fx_setup_dummy_gst_renderer
+ fun:tcase_run_checked_setup
+ fun:srunner_run_all
+ fun:main
+}
+{
+ <48>
+ Memcheck:Leak
+ fun:*
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ obj:/targets/*/lib/libc-2.5.so
+ fun:reg*
+ fun:mafw_source_create_objectid
+ fun:get_sample_clip_objectid
+ fun:*
+ fun:srunner_run_all
+ fun:main
+}
+{
+ <49>
+ Memcheck:Leak
+ fun:malloc
+ fun:emalloc
+ fun:suite_create
+ fun:configure_tests
+ fun:main
+}
+{
+ <50>
+ Memcheck:Leak
+ fun:malloc
+ fun:dbus_malloc
+ obj:/targets/*/usr/lib/libdbus-1.so.3.4.0
+ obj:/targets/*/usr/lib/libdbus-1.so.3.4.0
+ fun:dbus_bus_get
+ obj:/targets/*/usr/lib/libosso.so.1.3.0
+ fun:osso_initialize
+ fun:blanking_init
+ fun:mafw_gst_renderer_worker_new
+ fun:mafw_gst_renderer_init
+ fun:g_type_create_instance
+ obj:/targets/*/usr/lib/libgobject-2.0.so.0.1800.1
+}
+{
+ <51>
+ Memcheck:Leak
+ fun:malloc
+ fun:g_malloc
+ fun:g_strdup
+ obj:/targets/*/usr/lib/libgstreamer-0.10.so.0.18.0
+ fun:gst_registry_binary_read_cache
+ obj:/targets/*/usr/lib/libgstreamer-0.10.so.0.18.0
+ obj:/targets/*/usr/lib/libgstreamer-0.10.so.0.18.0
+ fun:g_option_context_parse
+ fun:gst_init_check
+ fun:gst_init
+ fun:mafw_gst_renderer_class_init
+ fun:mafw_gst_renderer_class_intern_init
+}
+{
+ <52>
+ Memcheck:Leak
+ fun:*
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libdl-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libdl-2.5.so
+ fun:dlopen
+ fun:g_module_open
+}
+{
+ <53>
+ Memcheck:Leak
+ fun:malloc
+ fun:g_malloc
+ fun:g_slice_alloc
+ fun:g_hash_table_new_full
+ fun:g_hash_table_new
+ fun:g_quark_from_static_string
+ fun:g_type_init_with_debug_flags
+ fun:g_type_init
+ fun:fx_setup_dummy_gst_renderer
+ fun:tcase_run_checked_setup
+ fun:srunner_run_all
+ fun:main
+}
+{
+ <54>
+ Memcheck:Leak
+ fun:*
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libdl-2.5.so
+ obj:/targets/*/lib/ld-2.5.so
+ obj:/targets/*/lib/libdl-2.5.so
+}
+{
+ <55>
+ Memcheck:Leak
+ fun:malloc
+ fun:fdopen
+ fun:tmpfile
+ fun:setup_pipe
+ fun:receive_test_result
+ fun:srunner_run_all
+ fun:main
+}
+++ /dev/null
-# Please keep this list sorted alphabetically
-#
-cs
-da
-de
-fi
-hu
-sk
+++ /dev/null
-# List of source files containing translatable strings.
-
-applet/cpmpsubtitles.c
-applet/cpmpsubtitles.desktop
+++ /dev/null
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# Roman Moravčík <roman.moravcik@gmail.com>, 2010.
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: mafw-gst-subtitles-renderer\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-18 15:46+0100\n"
-"PO-Revision-Date: 2010-01-19 09:56+0100\n"
-"Last-Translator: Roman Moravčík <roman.moravcik@gmail.com>\n"
-"Language-Team: Czech <>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: ../applet/cpmpsubtitles.c:59
-msgid "Regular"
-msgstr ""
-
-#: ../applet/cpmpsubtitles.c:60
-msgid "Italic"
-msgstr "Kurzíva"
-
-#: ../applet/cpmpsubtitles.c:61
-msgid "Bold"
-msgstr "Tučné"
-
-#: ../applet/cpmpsubtitles.c:62
-msgid "Italic Bold"
-msgstr "Tučné kurzíva"
-
-#: ../applet/cpmpsubtitles.c:187
-msgid "Current Locale"
-msgstr "Aktuální lokalizace"
-
-#: ../applet/cpmpsubtitles.c:189 ../applet/cpmpsubtitles.c:190
-#: ../applet/cpmpsubtitles.c:191 ../applet/cpmpsubtitles.c:192
-msgid "Arabic"
-msgstr "Arabské"
-
-#: ../applet/cpmpsubtitles.c:194
-msgid "Armenian"
-msgstr "Arménské"
-
-#: ../applet/cpmpsubtitles.c:196 ../applet/cpmpsubtitles.c:197
-#: ../applet/cpmpsubtitles.c:198
-msgid "Baltic"
-msgstr "Baltské"
-
-#: ../applet/cpmpsubtitles.c:200
-msgid "Celtic"
-msgstr "Keltské"
-
-#: ../applet/cpmpsubtitles.c:202 ../applet/cpmpsubtitles.c:203
-#: ../applet/cpmpsubtitles.c:204 ../applet/cpmpsubtitles.c:205
-msgid "Central European"
-msgstr "Střední Evropa"
-
-#: ../applet/cpmpsubtitles.c:207 ../applet/cpmpsubtitles.c:208
-#: ../applet/cpmpsubtitles.c:209 ../applet/cpmpsubtitles.c:210
-msgid "Chinese Simplified"
-msgstr "Zjednodušené čínské"
-
-#: ../applet/cpmpsubtitles.c:212 ../applet/cpmpsubtitles.c:213
-#: ../applet/cpmpsubtitles.c:214
-msgid "Chinese Traditional"
-msgstr "Tradiční čínské"
-
-#: ../applet/cpmpsubtitles.c:216
-msgid "Croatian"
-msgstr "Chorvatské"
-
-#: ../applet/cpmpsubtitles.c:218 ../applet/cpmpsubtitles.c:219
-#: ../applet/cpmpsubtitles.c:220 ../applet/cpmpsubtitles.c:221
-#: ../applet/cpmpsubtitles.c:222 ../applet/cpmpsubtitles.c:223
-msgid "Cyrillic"
-msgstr "Cyrilice"
-
-#: ../applet/cpmpsubtitles.c:225
-msgid "Cyrillic/Russian"
-msgstr "Cyrilice/ruské"
-
-#: ../applet/cpmpsubtitles.c:227 ../applet/cpmpsubtitles.c:228
-msgid "Cyrillic/Ukrainian"
-msgstr "Cyrilice/ukrajinské"
-
-#: ../applet/cpmpsubtitles.c:230
-msgid "Georgian"
-msgstr "Gruzínské"
-
-#: ../applet/cpmpsubtitles.c:232 ../applet/cpmpsubtitles.c:233
-#: ../applet/cpmpsubtitles.c:234
-msgid "Greek"
-msgstr "Řecké"
-
-#: ../applet/cpmpsubtitles.c:236
-msgid "Gujarati"
-msgstr "Gudžarátské"
-
-#: ../applet/cpmpsubtitles.c:238
-msgid "Gurmukhi"
-msgstr "Gurmuchské"
-
-#: ../applet/cpmpsubtitles.c:240 ../applet/cpmpsubtitles.c:241
-#: ../applet/cpmpsubtitles.c:242 ../applet/cpmpsubtitles.c:243
-msgid "Hebrew"
-msgstr "Hebrejské"
-
-#: ../applet/cpmpsubtitles.c:245
-msgid "Hebrew Visual"
-msgstr "Hebrejské vizuální"
-
-#: ../applet/cpmpsubtitles.c:247
-msgid "Hindi"
-msgstr "Hindské"
-
-#: ../applet/cpmpsubtitles.c:249
-msgid "Icelandic"
-msgstr "Islandské"
-
-#: ../applet/cpmpsubtitles.c:251 ../applet/cpmpsubtitles.c:252
-#: ../applet/cpmpsubtitles.c:253
-msgid "Japanese"
-msgstr "Japonské"
-
-#: ../applet/cpmpsubtitles.c:255 ../applet/cpmpsubtitles.c:256
-#: ../applet/cpmpsubtitles.c:257 ../applet/cpmpsubtitles.c:258
-msgid "Korean"
-msgstr "Korejské"
-
-#: ../applet/cpmpsubtitles.c:260
-msgid "Nordic"
-msgstr "Nordické"
-
-#: ../applet/cpmpsubtitles.c:262
-msgid "Persian"
-msgstr "Perské"
-
-#: ../applet/cpmpsubtitles.c:264 ../applet/cpmpsubtitles.c:265
-msgid "Romanian"
-msgstr "Rumunské"
-
-#: ../applet/cpmpsubtitles.c:267
-msgid "South European"
-msgstr "Jihoevropské"
-
-#: ../applet/cpmpsubtitles.c:269
-msgid "Thai"
-msgstr "Thajské"
-
-#: ../applet/cpmpsubtitles.c:271 ../applet/cpmpsubtitles.c:272
-#: ../applet/cpmpsubtitles.c:273 ../applet/cpmpsubtitles.c:274
-msgid "Turkish"
-msgstr "Turecké"
-
-#: ../applet/cpmpsubtitles.c:276 ../applet/cpmpsubtitles.c:277
-#: ../applet/cpmpsubtitles.c:278 ../applet/cpmpsubtitles.c:279
-#: ../applet/cpmpsubtitles.c:280
-msgid "Unicode"
-msgstr "Unicode"
-
-#: ../applet/cpmpsubtitles.c:282 ../applet/cpmpsubtitles.c:283
-#: ../applet/cpmpsubtitles.c:284 ../applet/cpmpsubtitles.c:285
-#: ../applet/cpmpsubtitles.c:286
-msgid "Western"
-msgstr "Západní"
-
-#: ../applet/cpmpsubtitles.c:288 ../applet/cpmpsubtitles.c:289
-#: ../applet/cpmpsubtitles.c:290
-msgid "Vietnamese"
-msgstr "Vietnamské"
-
-#: ../applet/cpmpsubtitles.c:427 ../applet/cpmpsubtitles.c:622
-msgid "Font"
-msgstr "Písmo"
-
-#: ../applet/cpmpsubtitles.c:593
-msgid "Automatically load subtitle files"
-msgstr "Automaticky nahrát titulky"
-
-#: ../applet/cpmpsubtitles.c:659
-msgid "Encoding"
-msgstr "Kódování"
-
-#: ../applet/cpmpsubtitles.c:724
-msgid "Subtitles"
-msgstr "Titulky"
+++ /dev/null
-# Danish translation of MAFW.
-# Copyright (C) 2010 MAFW & Joe Hansen.
-# This file is distributed under the same license as the MAFW package.
-# Joe Hansen <joedalton2@yahoo.dk>, 2010.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Development\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-02-01 04:03+0000\n"
-"PO-Revision-Date: 2010-02-01 17:30+01:00\n"
-"Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
-"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: ../applet/cpmpsubtitles.c:59
-msgid "Regular"
-msgstr "Normal"
-
-#: ../applet/cpmpsubtitles.c:60
-msgid "Italic"
-msgstr "Kursiv"
-
-#: ../applet/cpmpsubtitles.c:61
-msgid "Bold"
-msgstr "Fed"
-
-#: ../applet/cpmpsubtitles.c:62
-msgid "Italic Bold"
-msgstr "Kursiv og fed"
-
-#: ../applet/cpmpsubtitles.c:187 ../applet/cpmpsubtitles.c:188
-#: ../applet/cpmpsubtitles.c:189 ../applet/cpmpsubtitles.c:190
-msgid "Arabic"
-msgstr "Arabisk"
-
-#: ../applet/cpmpsubtitles.c:192
-msgid "Armenian"
-msgstr "Armensk"
-
-#: ../applet/cpmpsubtitles.c:194 ../applet/cpmpsubtitles.c:195
-#: ../applet/cpmpsubtitles.c:196
-msgid "Baltic"
-msgstr "Baltisk"
-
-#: ../applet/cpmpsubtitles.c:198
-msgid "Celtic"
-msgstr "Keltisk"
-
-#: ../applet/cpmpsubtitles.c:200 ../applet/cpmpsubtitles.c:201
-#: ../applet/cpmpsubtitles.c:202 ../applet/cpmpsubtitles.c:203
-msgid "Central European"
-msgstr "Centraleuropæisk"
-
-#: ../applet/cpmpsubtitles.c:205 ../applet/cpmpsubtitles.c:206
-#: ../applet/cpmpsubtitles.c:207 ../applet/cpmpsubtitles.c:208
-msgid "Chinese Simplified"
-msgstr "Forenklet kinesisk"
-
-#: ../applet/cpmpsubtitles.c:210 ../applet/cpmpsubtitles.c:211
-#: ../applet/cpmpsubtitles.c:212
-msgid "Chinese Traditional"
-msgstr "Traditionel kinesisk"
-
-#: ../applet/cpmpsubtitles.c:214
-msgid "Croatian"
-msgstr "Kroatisk"
-
-#: ../applet/cpmpsubtitles.c:216 ../applet/cpmpsubtitles.c:217
-#: ../applet/cpmpsubtitles.c:218 ../applet/cpmpsubtitles.c:219
-#: ../applet/cpmpsubtitles.c:220 ../applet/cpmpsubtitles.c:221
-msgid "Cyrillic"
-msgstr "Kyrillisk"
-
-#: ../applet/cpmpsubtitles.c:223
-msgid "Cyrillic/Russian"
-msgstr "Kyrillisk/russisk"
-
-#: ../applet/cpmpsubtitles.c:225 ../applet/cpmpsubtitles.c:226
-msgid "Cyrillic/Ukrainian"
-msgstr "Kyrillisk/ukrainsk"
-
-#: ../applet/cpmpsubtitles.c:228
-msgid "Georgian"
-msgstr "Georgisk"
-
-#: ../applet/cpmpsubtitles.c:230 ../applet/cpmpsubtitles.c:231
-#: ../applet/cpmpsubtitles.c:232
-msgid "Greek"
-msgstr "Græsk"
-
-#: ../applet/cpmpsubtitles.c:234
-msgid "Gujarati"
-msgstr "Gujarati"
-
-#: ../applet/cpmpsubtitles.c:236
-msgid "Gurmukhi"
-msgstr "Gurmukhi"
-
-#: ../applet/cpmpsubtitles.c:238 ../applet/cpmpsubtitles.c:239
-#: ../applet/cpmpsubtitles.c:240 ../applet/cpmpsubtitles.c:241
-msgid "Hebrew"
-msgstr "Hebraisk"
-
-#: ../applet/cpmpsubtitles.c:243
-msgid "Hebrew Visual"
-msgstr "Visuelt hebraisk"
-
-#: ../applet/cpmpsubtitles.c:245
-msgid "Hindi"
-msgstr "Hindi"
-
-#: ../applet/cpmpsubtitles.c:247
-msgid "Icelandic"
-msgstr "Islandsk"
-
-#: ../applet/cpmpsubtitles.c:249 ../applet/cpmpsubtitles.c:250
-#: ../applet/cpmpsubtitles.c:251
-msgid "Japanese"
-msgstr "Japansk"
-
-#: ../applet/cpmpsubtitles.c:253 ../applet/cpmpsubtitles.c:254
-#: ../applet/cpmpsubtitles.c:255 ../applet/cpmpsubtitles.c:256
-msgid "Korean"
-msgstr "Koreansk"
-
-#: ../applet/cpmpsubtitles.c:258
-msgid "Nordic"
-msgstr "Nordisk"
-
-#: ../applet/cpmpsubtitles.c:260
-msgid "Persian"
-msgstr "Iransk"
-
-#: ../applet/cpmpsubtitles.c:262 ../applet/cpmpsubtitles.c:263
-msgid "Romanian"
-msgstr "Rumænsk"
-
-#: ../applet/cpmpsubtitles.c:265
-msgid "South European"
-msgstr "Sydeuropæisk"
-
-#: ../applet/cpmpsubtitles.c:267
-msgid "Thai"
-msgstr "Thai"
-
-#: ../applet/cpmpsubtitles.c:269 ../applet/cpmpsubtitles.c:270
-#: ../applet/cpmpsubtitles.c:271 ../applet/cpmpsubtitles.c:272
-msgid "Turkish"
-msgstr "Tyrkisk"
-
-#: ../applet/cpmpsubtitles.c:274 ../applet/cpmpsubtitles.c:275
-#: ../applet/cpmpsubtitles.c:276 ../applet/cpmpsubtitles.c:277
-#: ../applet/cpmpsubtitles.c:278
-msgid "Unicode"
-msgstr "Unicode"
-
-#: ../applet/cpmpsubtitles.c:280 ../applet/cpmpsubtitles.c:281
-#: ../applet/cpmpsubtitles.c:282 ../applet/cpmpsubtitles.c:283
-#: ../applet/cpmpsubtitles.c:284
-msgid "Western"
-msgstr "Vestligt"
-
-#: ../applet/cpmpsubtitles.c:286 ../applet/cpmpsubtitles.c:287
-#: ../applet/cpmpsubtitles.c:288
-msgid "Vietnamese"
-msgstr "Vietnamesisk"
-
-#: ../applet/cpmpsubtitles.c:290
-msgid "Current Locale"
-msgstr "Nuværende sprog"
-
-#: ../applet/cpmpsubtitles.c:432 ../applet/cpmpsubtitles.c:631
-msgid "Font"
-msgstr "Skrifttype"
-
-#: ../applet/cpmpsubtitles.c:602
-msgid "Automatically load subtitle files"
-msgstr "Indlæs automatisk undertekstfiler"
-
-# Det skal vel ikke være kodning her, men sprog?
-#: ../applet/cpmpsubtitles.c:668
-msgid "Encoding"
-msgstr "Sprog"
-
-#: ../applet/cpmpsubtitles.c:733
-msgid "Subtitles"
-msgstr "Undertekster"
+++ /dev/null
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: mafw-gst-subtitles-render\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-20 14:17+0000\n"
-"PO-Revision-Date: 2010-01-20 19:01+0100\n"
-"Last-Translator: Philipp Zabel <philipp.zabel@gmail.com>\n"
-"Language-Team: German\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: German\n"
-"X-Poedit-Country: GERMANY\n"
-
-#: ../applet/cpmpsubtitles.c:59
-msgid "Regular"
-msgstr "Normal"
-
-#: ../applet/cpmpsubtitles.c:60
-msgid "Italic"
-msgstr "Kursiv"
-
-#: ../applet/cpmpsubtitles.c:61
-msgid "Bold"
-msgstr "Fett"
-
-#: ../applet/cpmpsubtitles.c:62
-msgid "Italic Bold"
-msgstr "Fett Kursiv"
-
-#: ../applet/cpmpsubtitles.c:187
-#: ../applet/cpmpsubtitles.c:188
-#: ../applet/cpmpsubtitles.c:189
-#: ../applet/cpmpsubtitles.c:190
-msgid "Arabic"
-msgstr "Arabisch"
-
-#: ../applet/cpmpsubtitles.c:192
-msgid "Armenian"
-msgstr "Armenisch"
-
-#: ../applet/cpmpsubtitles.c:194
-#: ../applet/cpmpsubtitles.c:195
-#: ../applet/cpmpsubtitles.c:196
-msgid "Baltic"
-msgstr "Baltisch"
-
-#: ../applet/cpmpsubtitles.c:198
-msgid "Celtic"
-msgstr "Keltisch"
-
-#: ../applet/cpmpsubtitles.c:200
-#: ../applet/cpmpsubtitles.c:201
-#: ../applet/cpmpsubtitles.c:202
-#: ../applet/cpmpsubtitles.c:203
-msgid "Central European"
-msgstr "Zentraleuropäisch"
-
-#: ../applet/cpmpsubtitles.c:205
-#: ../applet/cpmpsubtitles.c:206
-#: ../applet/cpmpsubtitles.c:207
-#: ../applet/cpmpsubtitles.c:208
-msgid "Chinese Simplified"
-msgstr "Vereinfachtes Chinesisch"
-
-#: ../applet/cpmpsubtitles.c:210
-#: ../applet/cpmpsubtitles.c:211
-#: ../applet/cpmpsubtitles.c:212
-msgid "Chinese Traditional"
-msgstr "Traditionelles Chinesisch"
-
-#: ../applet/cpmpsubtitles.c:214
-msgid "Croatian"
-msgstr "Kroatisch"
-
-#: ../applet/cpmpsubtitles.c:216
-#: ../applet/cpmpsubtitles.c:217
-#: ../applet/cpmpsubtitles.c:218
-#: ../applet/cpmpsubtitles.c:219
-#: ../applet/cpmpsubtitles.c:220
-#: ../applet/cpmpsubtitles.c:221
-msgid "Cyrillic"
-msgstr "Kyrillisch"
-
-#: ../applet/cpmpsubtitles.c:223
-msgid "Cyrillic/Russian"
-msgstr "Kyrillisch/Russisch"
-
-#: ../applet/cpmpsubtitles.c:225
-#: ../applet/cpmpsubtitles.c:226
-msgid "Cyrillic/Ukrainian"
-msgstr "Kyrillisch/Ukrainisch"
-
-#: ../applet/cpmpsubtitles.c:228
-msgid "Georgian"
-msgstr "Georgisch"
-
-#: ../applet/cpmpsubtitles.c:230
-#: ../applet/cpmpsubtitles.c:231
-#: ../applet/cpmpsubtitles.c:232
-msgid "Greek"
-msgstr "Griechisch"
-
-#: ../applet/cpmpsubtitles.c:234
-msgid "Gujarati"
-msgstr "Gujarati"
-
-#: ../applet/cpmpsubtitles.c:236
-msgid "Gurmukhi"
-msgstr "Gurmukhi"
-
-#: ../applet/cpmpsubtitles.c:238
-#: ../applet/cpmpsubtitles.c:239
-#: ../applet/cpmpsubtitles.c:240
-#: ../applet/cpmpsubtitles.c:241
-msgid "Hebrew"
-msgstr "Hebräisch"
-
-#: ../applet/cpmpsubtitles.c:243
-msgid "Hebrew Visual"
-msgstr "Visuelles Hebräisch"
-
-#: ../applet/cpmpsubtitles.c:245
-msgid "Hindi"
-msgstr "Hindi"
-
-#: ../applet/cpmpsubtitles.c:247
-msgid "Icelandic"
-msgstr "Isländisch"
-
-#: ../applet/cpmpsubtitles.c:249
-#: ../applet/cpmpsubtitles.c:250
-#: ../applet/cpmpsubtitles.c:251
-msgid "Japanese"
-msgstr "Japanisch"
-
-#: ../applet/cpmpsubtitles.c:253
-#: ../applet/cpmpsubtitles.c:254
-#: ../applet/cpmpsubtitles.c:255
-#: ../applet/cpmpsubtitles.c:256
-msgid "Korean"
-msgstr "Koreanisch"
-
-#: ../applet/cpmpsubtitles.c:258
-msgid "Nordic"
-msgstr "Nordisch"
-
-#: ../applet/cpmpsubtitles.c:260
-msgid "Persian"
-msgstr "Persisch"
-
-#: ../applet/cpmpsubtitles.c:262
-#: ../applet/cpmpsubtitles.c:263
-msgid "Romanian"
-msgstr "Rumänisch"
-
-#: ../applet/cpmpsubtitles.c:265
-msgid "South European"
-msgstr "Südeuropäisch"
-
-#: ../applet/cpmpsubtitles.c:267
-msgid "Thai"
-msgstr "Thai"
-
-#: ../applet/cpmpsubtitles.c:269
-#: ../applet/cpmpsubtitles.c:270
-#: ../applet/cpmpsubtitles.c:271
-#: ../applet/cpmpsubtitles.c:272
-msgid "Turkish"
-msgstr "Türkisch"
-
-#: ../applet/cpmpsubtitles.c:274
-#: ../applet/cpmpsubtitles.c:275
-#: ../applet/cpmpsubtitles.c:276
-#: ../applet/cpmpsubtitles.c:277
-#: ../applet/cpmpsubtitles.c:278
-msgid "Unicode"
-msgstr "Unicode"
-
-#: ../applet/cpmpsubtitles.c:280
-#: ../applet/cpmpsubtitles.c:281
-#: ../applet/cpmpsubtitles.c:282
-#: ../applet/cpmpsubtitles.c:283
-#: ../applet/cpmpsubtitles.c:284
-msgid "Western"
-msgstr "Westlich"
-
-#: ../applet/cpmpsubtitles.c:286
-#: ../applet/cpmpsubtitles.c:287
-#: ../applet/cpmpsubtitles.c:288
-msgid "Vietnamese"
-msgstr "Vietnamesisch"
-
-#: ../applet/cpmpsubtitles.c:290
-msgid "Current Locale"
-msgstr "Aktuelle Sprache/Region"
-
-#: ../applet/cpmpsubtitles.c:432
-#: ../applet/cpmpsubtitles.c:631
-msgid "Font"
-msgstr "Schrift"
-
-#: ../applet/cpmpsubtitles.c:602
-msgid "Automatically load subtitle files"
-msgstr "Untertiteldateien automatisch laden"
-
-#: ../applet/cpmpsubtitles.c:668
-msgid "Encoding"
-msgstr "Codierung"
-
-#: ../applet/cpmpsubtitles.c:733
-msgid "Subtitles"
-msgstr "Untertitel"
-
+++ /dev/null
-# This is an fi_FI "translation" file for MAFW Gstreamer renderer with subtitles
-# support. To translate this to another language, first copy this file to a
-# filename with the appropriate language/country code, then modify the "msgstr"
-# strings with the correct translation.
-# Copyright (C) 2010, Marko Vertainen
-# This file is distributed under the same license as the MAFW Gstreamer renderer
-# with subtitles support package.
-# FIRST AUTHOR <marko.vertainen@iki.fi>, 2010.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-04-21 04:04+0000\n"
-"PO-Revision-Date: 2010-02-02 16:46+0200\n"
-"Last-Translator: Marko Vertainen <marko.vertainen@iki.fi>\n"
-"Language-Team: FI <LL@li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: ../applet/cpmpsubtitles.c:59
-msgid "Regular"
-msgstr "Tavallinen"
-
-#: ../applet/cpmpsubtitles.c:60
-msgid "Italic"
-msgstr "Kursivoitu"
-
-#: ../applet/cpmpsubtitles.c:61
-msgid "Bold"
-msgstr "Lihavoitu"
-
-#: ../applet/cpmpsubtitles.c:62
-msgid "Italic Bold"
-msgstr "Lihavoitu kursiivi"
-
-#: ../applet/cpmpsubtitles.c:187 ../applet/cpmpsubtitles.c:188
-#: ../applet/cpmpsubtitles.c:189 ../applet/cpmpsubtitles.c:190
-msgid "Arabic"
-msgstr "Arabialainen"
-
-#: ../applet/cpmpsubtitles.c:192
-msgid "Armenian"
-msgstr "Armenialainen"
-
-#: ../applet/cpmpsubtitles.c:194 ../applet/cpmpsubtitles.c:195
-#: ../applet/cpmpsubtitles.c:196
-msgid "Baltic"
-msgstr "Balttialainen"
-
-#: ../applet/cpmpsubtitles.c:198
-msgid "Celtic"
-msgstr "Kelttiläinen"
-
-#: ../applet/cpmpsubtitles.c:200 ../applet/cpmpsubtitles.c:201
-#: ../applet/cpmpsubtitles.c:202 ../applet/cpmpsubtitles.c:203
-msgid "Central European"
-msgstr "Keskieurooppalainen"
-
-#: ../applet/cpmpsubtitles.c:205 ../applet/cpmpsubtitles.c:206
-#: ../applet/cpmpsubtitles.c:207 ../applet/cpmpsubtitles.c:208
-msgid "Chinese Simplified"
-msgstr "Kiinalainen, yksinkertaistettu"
-
-#: ../applet/cpmpsubtitles.c:210 ../applet/cpmpsubtitles.c:211
-#: ../applet/cpmpsubtitles.c:212
-msgid "Chinese Traditional"
-msgstr "Kiinalainen, perinteinen"
-
-#: ../applet/cpmpsubtitles.c:214
-msgid "Croatian"
-msgstr "Kroatialainen"
-
-#: ../applet/cpmpsubtitles.c:216 ../applet/cpmpsubtitles.c:217
-#: ../applet/cpmpsubtitles.c:218 ../applet/cpmpsubtitles.c:219
-#: ../applet/cpmpsubtitles.c:220 ../applet/cpmpsubtitles.c:221
-msgid "Cyrillic"
-msgstr "Kyriilinen"
-
-#: ../applet/cpmpsubtitles.c:223
-msgid "Cyrillic/Russian"
-msgstr "Kyriilinen/Venäläinen"
-
-#: ../applet/cpmpsubtitles.c:225 ../applet/cpmpsubtitles.c:226
-msgid "Cyrillic/Ukrainian"
-msgstr "Kyriilinen/Ukrainalainen"
-
-#: ../applet/cpmpsubtitles.c:228
-msgid "Georgian"
-msgstr "Georgialainen"
-
-#: ../applet/cpmpsubtitles.c:230 ../applet/cpmpsubtitles.c:231
-#: ../applet/cpmpsubtitles.c:232
-msgid "Greek"
-msgstr "Kreikkalainen"
-
-#: ../applet/cpmpsubtitles.c:234
-msgid "Gujarati"
-msgstr "Gujarati"
-
-#: ../applet/cpmpsubtitles.c:236
-msgid "Gurmukhi"
-msgstr "Gurmukhi"
-
-#: ../applet/cpmpsubtitles.c:238 ../applet/cpmpsubtitles.c:239
-#: ../applet/cpmpsubtitles.c:240 ../applet/cpmpsubtitles.c:241
-msgid "Hebrew"
-msgstr "Hebrealainen"
-
-#: ../applet/cpmpsubtitles.c:243
-msgid "Hebrew Visual"
-msgstr "Hebrealainen, visuaalinen"
-
-#: ../applet/cpmpsubtitles.c:245
-msgid "Hindi"
-msgstr "Hindilainen"
-
-#: ../applet/cpmpsubtitles.c:247
-msgid "Icelandic"
-msgstr "Islantilainen"
-
-#: ../applet/cpmpsubtitles.c:249 ../applet/cpmpsubtitles.c:250
-#: ../applet/cpmpsubtitles.c:251
-msgid "Japanese"
-msgstr "Japanilainen"
-
-#: ../applet/cpmpsubtitles.c:253 ../applet/cpmpsubtitles.c:254
-#: ../applet/cpmpsubtitles.c:255 ../applet/cpmpsubtitles.c:256
-msgid "Korean"
-msgstr "Korealainen"
-
-#: ../applet/cpmpsubtitles.c:258
-msgid "Nordic"
-msgstr "Pohjoismaalainen"
-
-#: ../applet/cpmpsubtitles.c:260
-msgid "Persian"
-msgstr "Persialainen"
-
-#: ../applet/cpmpsubtitles.c:262 ../applet/cpmpsubtitles.c:263
-msgid "Romanian"
-msgstr "Romanialainen"
-
-#: ../applet/cpmpsubtitles.c:265
-msgid "South European"
-msgstr "Eteläeurooppalainen"
-
-#: ../applet/cpmpsubtitles.c:267
-msgid "Thai"
-msgstr "Thaimaalainen"
-
-#: ../applet/cpmpsubtitles.c:269 ../applet/cpmpsubtitles.c:270
-#: ../applet/cpmpsubtitles.c:271 ../applet/cpmpsubtitles.c:272
-msgid "Turkish"
-msgstr "Turkkilainen"
-
-#: ../applet/cpmpsubtitles.c:274 ../applet/cpmpsubtitles.c:275
-#: ../applet/cpmpsubtitles.c:276 ../applet/cpmpsubtitles.c:277
-#: ../applet/cpmpsubtitles.c:278
-msgid "Unicode"
-msgstr "Unicode"
-
-#: ../applet/cpmpsubtitles.c:280 ../applet/cpmpsubtitles.c:281
-#: ../applet/cpmpsubtitles.c:282 ../applet/cpmpsubtitles.c:283
-#: ../applet/cpmpsubtitles.c:284
-msgid "Western"
-msgstr "Länsimainen"
-
-#: ../applet/cpmpsubtitles.c:286 ../applet/cpmpsubtitles.c:287
-#: ../applet/cpmpsubtitles.c:288
-msgid "Vietnamese"
-msgstr "Vietnamilainen"
-
-#: ../applet/cpmpsubtitles.c:290
-msgid "Current Locale"
-msgstr "Nykyinen maa-asetus"
-
-#: ../applet/cpmpsubtitles.c:432 ../applet/cpmpsubtitles.c:631
-msgid "Font"
-msgstr "Kirjasin"
-
-#: ../applet/cpmpsubtitles.c:602
-msgid "Automatically load subtitle files"
-msgstr "Lataa tekstitystiedosto automaattisesti"
-
-#: ../applet/cpmpsubtitles.c:668
-msgid "Encoding"
-msgstr "Merkistökoodaus"
-
-#: ../applet/cpmpsubtitles.c:733
-msgid "Subtitles"
-msgstr "Tekstitys"
+++ /dev/null
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: subtitle hun loc\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-02-20 04:03+0000\n"
-"PO-Revision-Date: 2010-02-21 13:47-0000\n"
-"Last-Translator: Gyorgy Lakatos <redon13@gmail.com>\n"
-"Language-Team: Hungarian Translater Team <redon13@gmail.com>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Hungarian\n"
-"X-Poedit-Country: UNITED KINGDOM\n"
-
-#: ../applet/cpmpsubtitles.c:59
-msgid "Regular"
-msgstr "Szabályos"
-
-#: ../applet/cpmpsubtitles.c:60
-msgid "Italic"
-msgstr "Itáliai"
-
-#: ../applet/cpmpsubtitles.c:61
-msgid "Bold"
-msgstr "Félkövér"
-
-#: ../applet/cpmpsubtitles.c:62
-msgid "Italic Bold"
-msgstr "Itáliai félkövér"
-
-#: ../applet/cpmpsubtitles.c:187
-#: ../applet/cpmpsubtitles.c:188
-#: ../applet/cpmpsubtitles.c:189
-#: ../applet/cpmpsubtitles.c:190
-msgid "Arabic"
-msgstr "Arab"
-
-#: ../applet/cpmpsubtitles.c:192
-msgid "Armenian"
-msgstr "Armenian"
-
-#: ../applet/cpmpsubtitles.c:194
-#: ../applet/cpmpsubtitles.c:195
-#: ../applet/cpmpsubtitles.c:196
-msgid "Baltic"
-msgstr "Balti"
-
-#: ../applet/cpmpsubtitles.c:198
-msgid "Celtic"
-msgstr "Kelta"
-
-#: ../applet/cpmpsubtitles.c:200
-#: ../applet/cpmpsubtitles.c:201
-#: ../applet/cpmpsubtitles.c:202
-#: ../applet/cpmpsubtitles.c:203
-msgid "Central European"
-msgstr "Közép Európai"
-
-#: ../applet/cpmpsubtitles.c:205
-#: ../applet/cpmpsubtitles.c:206
-#: ../applet/cpmpsubtitles.c:207
-#: ../applet/cpmpsubtitles.c:208
-msgid "Chinese Simplified"
-msgstr "Kínai (egyszerü)"
-
-#: ../applet/cpmpsubtitles.c:210
-#: ../applet/cpmpsubtitles.c:211
-#: ../applet/cpmpsubtitles.c:212
-msgid "Chinese Traditional"
-msgstr "Kínai (hagyományos)"
-
-#: ../applet/cpmpsubtitles.c:214
-msgid "Croatian"
-msgstr "Horvát"
-
-#: ../applet/cpmpsubtitles.c:216
-#: ../applet/cpmpsubtitles.c:217
-#: ../applet/cpmpsubtitles.c:218
-#: ../applet/cpmpsubtitles.c:219
-#: ../applet/cpmpsubtitles.c:220
-#: ../applet/cpmpsubtitles.c:221
-msgid "Cyrillic"
-msgstr "Ciril"
-
-#: ../applet/cpmpsubtitles.c:223
-msgid "Cyrillic/Russian"
-msgstr "Ciril/Orosz"
-
-#: ../applet/cpmpsubtitles.c:225
-#: ../applet/cpmpsubtitles.c:226
-msgid "Cyrillic/Ukrainian"
-msgstr "Ciril/Ukrán"
-
-#: ../applet/cpmpsubtitles.c:228
-msgid "Georgian"
-msgstr "Georgian"
-
-#: ../applet/cpmpsubtitles.c:230
-#: ../applet/cpmpsubtitles.c:231
-#: ../applet/cpmpsubtitles.c:232
-msgid "Greek"
-msgstr "Görög"
-
-#: ../applet/cpmpsubtitles.c:234
-msgid "Gujarati"
-msgstr "Gujarati"
-
-#: ../applet/cpmpsubtitles.c:236
-msgid "Gurmukhi"
-msgstr "Gurmukhi"
-
-#: ../applet/cpmpsubtitles.c:238
-#: ../applet/cpmpsubtitles.c:239
-#: ../applet/cpmpsubtitles.c:240
-#: ../applet/cpmpsubtitles.c:241
-msgid "Hebrew"
-msgstr "Héber"
-
-#: ../applet/cpmpsubtitles.c:243
-msgid "Hebrew Visual"
-msgstr "Héber (hagyományos)"
-
-#: ../applet/cpmpsubtitles.c:245
-msgid "Hindi"
-msgstr "Hindi"
-
-#: ../applet/cpmpsubtitles.c:247
-msgid "Icelandic"
-msgstr "Izlandi"
-
-#: ../applet/cpmpsubtitles.c:249
-#: ../applet/cpmpsubtitles.c:250
-#: ../applet/cpmpsubtitles.c:251
-msgid "Japanese"
-msgstr "Japán"
-
-#: ../applet/cpmpsubtitles.c:253
-#: ../applet/cpmpsubtitles.c:254
-#: ../applet/cpmpsubtitles.c:255
-#: ../applet/cpmpsubtitles.c:256
-msgid "Korean"
-msgstr "Koreai"
-
-#: ../applet/cpmpsubtitles.c:258
-msgid "Nordic"
-msgstr "Nordic"
-
-#: ../applet/cpmpsubtitles.c:260
-msgid "Persian"
-msgstr "Perzsa"
-
-#: ../applet/cpmpsubtitles.c:262
-#: ../applet/cpmpsubtitles.c:263
-msgid "Romanian"
-msgstr "Román"
-
-#: ../applet/cpmpsubtitles.c:265
-msgid "South European"
-msgstr "Dél Európai"
-
-#: ../applet/cpmpsubtitles.c:267
-msgid "Thai"
-msgstr "Thai"
-
-#: ../applet/cpmpsubtitles.c:269
-#: ../applet/cpmpsubtitles.c:270
-#: ../applet/cpmpsubtitles.c:271
-#: ../applet/cpmpsubtitles.c:272
-msgid "Turkish"
-msgstr "Török"
-
-#: ../applet/cpmpsubtitles.c:274
-#: ../applet/cpmpsubtitles.c:275
-#: ../applet/cpmpsubtitles.c:276
-#: ../applet/cpmpsubtitles.c:277
-#: ../applet/cpmpsubtitles.c:278
-msgid "Unicode"
-msgstr "Unicode"
-
-#: ../applet/cpmpsubtitles.c:280
-#: ../applet/cpmpsubtitles.c:281
-#: ../applet/cpmpsubtitles.c:282
-#: ../applet/cpmpsubtitles.c:283
-#: ../applet/cpmpsubtitles.c:284
-msgid "Western"
-msgstr "Nyugati"
-
-#: ../applet/cpmpsubtitles.c:286
-#: ../applet/cpmpsubtitles.c:287
-#: ../applet/cpmpsubtitles.c:288
-msgid "Vietnamese"
-msgstr "Vietnám"
-
-#: ../applet/cpmpsubtitles.c:290
-msgid "Current Locale"
-msgstr "Helyi"
-
-#: ../applet/cpmpsubtitles.c:432
-#: ../applet/cpmpsubtitles.c:631
-msgid "Font"
-msgstr "Betű méret"
-
-#: ../applet/cpmpsubtitles.c:602
-msgid "Automatically load subtitle files"
-msgstr "Autómatikus felirat file megnyitás"
-
-#: ../applet/cpmpsubtitles.c:668
-msgid "Encoding"
-msgstr "Kódolás"
-
-#: ../applet/cpmpsubtitles.c:733
-msgid "Subtitles"
-msgstr "Felirat"
-
+++ /dev/null
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# Roman Moravčík <roman.moravcik@gmail.com>, 2010.
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: mafw-gst-subtitles-renderer\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-18 14:36+0100\n"
-"PO-Revision-Date: 2010-01-19 09:52+0100\n"
-"Last-Translator: Roman Moravčík <roman.moravcik@gmail.com>\n"
-"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: ../applet/cpmpsubtitles.c:56
-msgid "Regular"
-msgstr "Normálne"
-
-#: ../applet/cpmpsubtitles.c:57
-msgid "Italic"
-msgstr "Kurzíva"
-
-#: ../applet/cpmpsubtitles.c:58
-msgid "Bold"
-msgstr "Tučné"
-
-#: ../applet/cpmpsubtitles.c:59
-msgid "Italic Bold"
-msgstr "Tučné kurzíva"
-
-#: ../applet/cpmpsubtitles.c:184
-msgid "Current Locale"
-msgstr "Súčasné miestne"
-
-#: ../applet/cpmpsubtitles.c:186 ../applet/cpmpsubtitles.c:187
-#: ../applet/cpmpsubtitles.c:188 ../applet/cpmpsubtitles.c:189
-msgid "Arabic"
-msgstr "Arabské"
-
-#: ../applet/cpmpsubtitles.c:191
-msgid "Armenian"
-msgstr "Arménske"
-
-#: ../applet/cpmpsubtitles.c:193 ../applet/cpmpsubtitles.c:194
-#: ../applet/cpmpsubtitles.c:195
-msgid "Baltic"
-msgstr "Baltské"
-
-#: ../applet/cpmpsubtitles.c:197
-msgid "Celtic"
-msgstr "Keltské"
-
-#: ../applet/cpmpsubtitles.c:199 ../applet/cpmpsubtitles.c:200
-#: ../applet/cpmpsubtitles.c:201 ../applet/cpmpsubtitles.c:202
-msgid "Central European"
-msgstr "Stredná Európa"
-
-#: ../applet/cpmpsubtitles.c:204 ../applet/cpmpsubtitles.c:205
-#: ../applet/cpmpsubtitles.c:206 ../applet/cpmpsubtitles.c:207
-msgid "Chinese Simplified"
-msgstr "Zjednodušené čínske"
-
-#: ../applet/cpmpsubtitles.c:209 ../applet/cpmpsubtitles.c:210
-#: ../applet/cpmpsubtitles.c:211
-msgid "Chinese Traditional"
-msgstr "Tradičné čínske"
-
-#: ../applet/cpmpsubtitles.c:213
-msgid "Croatian"
-msgstr "Chorvátske"
-
-#: ../applet/cpmpsubtitles.c:215 ../applet/cpmpsubtitles.c:216
-#: ../applet/cpmpsubtitles.c:217 ../applet/cpmpsubtitles.c:218
-#: ../applet/cpmpsubtitles.c:219 ../applet/cpmpsubtitles.c:220
-msgid "Cyrillic"
-msgstr "Cyrilika"
-
-#: ../applet/cpmpsubtitles.c:222
-msgid "Cyrillic/Russian"
-msgstr "Cyrilika/Ruské"
-
-#: ../applet/cpmpsubtitles.c:224 ../applet/cpmpsubtitles.c:225
-msgid "Cyrillic/Ukrainian"
-msgstr "Cyrilika/Ukrajinské"
-
-#: ../applet/cpmpsubtitles.c:227
-msgid "Georgian"
-msgstr "Gruzínske"
-
-#: ../applet/cpmpsubtitles.c:229 ../applet/cpmpsubtitles.c:230
-#: ../applet/cpmpsubtitles.c:231
-msgid "Greek"
-msgstr "Grécke"
-
-#: ../applet/cpmpsubtitles.c:233
-msgid "Gujarati"
-msgstr "Gudžarátske"
-
-#: ../applet/cpmpsubtitles.c:235
-msgid "Gurmukhi"
-msgstr "Chorvátske"
-
-#: ../applet/cpmpsubtitles.c:237 ../applet/cpmpsubtitles.c:238
-#: ../applet/cpmpsubtitles.c:239 ../applet/cpmpsubtitles.c:240
-msgid "Hebrew"
-msgstr "Chorvátske"
-
-#: ../applet/cpmpsubtitles.c:242
-msgid "Hebrew Visual"
-msgstr "Hebrejské vizuálne"
-
-#: ../applet/cpmpsubtitles.c:244
-msgid "Hindi"
-msgstr "Hindustánske"
-
-#: ../applet/cpmpsubtitles.c:246
-msgid "Icelandic"
-msgstr "Islandské"
-
-#: ../applet/cpmpsubtitles.c:248 ../applet/cpmpsubtitles.c:249
-#: ../applet/cpmpsubtitles.c:250
-msgid "Japanese"
-msgstr "Japonské"
-
-#: ../applet/cpmpsubtitles.c:252 ../applet/cpmpsubtitles.c:253
-#: ../applet/cpmpsubtitles.c:254 ../applet/cpmpsubtitles.c:255
-msgid "Korean"
-msgstr "Kórejské"
-
-#: ../applet/cpmpsubtitles.c:257
-msgid "Nordic"
-msgstr "Severogermánske"
-
-#: ../applet/cpmpsubtitles.c:259
-msgid "Persian"
-msgstr "Perzské"
-
-#: ../applet/cpmpsubtitles.c:261 ../applet/cpmpsubtitles.c:262
-msgid "Romanian"
-msgstr "Rumunské"
-
-#: ../applet/cpmpsubtitles.c:264
-msgid "South European"
-msgstr "Južná Európa"
-
-#: ../applet/cpmpsubtitles.c:266
-msgid "Thai"
-msgstr "Thajské"
-
-#: ../applet/cpmpsubtitles.c:268 ../applet/cpmpsubtitles.c:269
-#: ../applet/cpmpsubtitles.c:270 ../applet/cpmpsubtitles.c:271
-msgid "Turkish"
-msgstr "Turecké"
-
-#: ../applet/cpmpsubtitles.c:273 ../applet/cpmpsubtitles.c:274
-#: ../applet/cpmpsubtitles.c:275 ../applet/cpmpsubtitles.c:276
-#: ../applet/cpmpsubtitles.c:277
-msgid "Unicode"
-msgstr "Unicode"
-
-#: ../applet/cpmpsubtitles.c:279 ../applet/cpmpsubtitles.c:280
-#: ../applet/cpmpsubtitles.c:281 ../applet/cpmpsubtitles.c:282
-#: ../applet/cpmpsubtitles.c:283
-msgid "Western"
-msgstr "Západné"
-
-#: ../applet/cpmpsubtitles.c:285 ../applet/cpmpsubtitles.c:286
-#: ../applet/cpmpsubtitles.c:287
-msgid "Vietnamese"
-msgstr "Vietnamské"
-
-#: ../applet/cpmpsubtitles.c:424 ../applet/cpmpsubtitles.c:584
-msgid "Font"
-msgstr "Písmo"
-
-#: ../applet/cpmpsubtitles.c:555
-msgid "Automatically load subtitle files"
-msgstr "Automaticky načítať súbor s titulkami"
-
-#: ../applet/cpmpsubtitles.c:620
-msgid "Encoding"
-msgstr "Kódovanie"
-
-#: ../applet/cpmpsubtitles.c:685
-msgid "Subtitles"
-msgstr "Titulky"
+++ /dev/null
-#
-# Makefile.am for MAFW gst renderer library.
-#
-# Author: Visa Smolander <visa.smolander@nokia.com>
-#
-# Copyright (C) 2007, 2008, 2009 Nokia. All rights reserved.
-
-TESTS = check-mafw-gst-renderer
-TESTS_ENVIRONMENT = CK_FORK=yes \
- TESTS_DIR=@abs_srcdir@
-
-noinst_PROGRAMS = $(TESTS)
-
-AM_CFLAGS = $(_CFLAGS)
-AM_LDFLAGS = $(_LDFLAGS)
-
-INCLUDES = -I$(top_srcdir)/libmafw-gst-renderer \
- $(DEPS_CFLAGS) \
- $(DEPS_TESTS_CFLAGS) \
- $(CHECKMORE_CFLAGS)
-
-LDADD = $(CHECKMORE_LIBS) \
- $(DEPS_LIBS) \
- $(DEPS_TESTS_LIBS) \
- $(top_builddir)/libmafw-gst-renderer/mafw-gst-renderer.la \
- -lgstinterfaces-0.10 -lgsttag-0.10
-
-if HAVE_GDKPIXBUF
-INCLUDES += $(GDKPIXBUF_CFLAGS)
-LDADD += $(GDKPIXBUF_LIBS)
-endif
-
-if HAVE_CONIC
-INCLUDES += $(CONIC_CFLAGS)
-LDADD += $(CONIC_LIBS)
-endif
-
-EXTRA_DIST = media/test.wav media/test.avi media/testframe.png
-
-# -----------------------------------------------
-# Test programs build specs
-# -----------------------------------------------
-
-check_mafw_gst_renderer_SOURCES = check-main.c \
- check-mafw-gst-renderer.c \
- mafw-mock-playlist.c mafw-mock-playlist.h \
- mafw-mock-pulseaudio.c mafw-mock-pulseaudio.h
-
-CLEANFILES = $(TESTS) mafw.db *.gcno *.gcda
-MAINTAINERCLEANFILES = Makefile.in
-
-# Run valgrind on tests.
-VG_OPTS := --suppressions=test.suppressions --tool=memcheck \
- --leak-check=full --show-reachable=yes
-vg: $(TESTS)
- for p in $^; do \
- G_SLICE=always-malloc G_DEBUG=gc-friendly WAIT_TIMEOUT=25000 \
- libtool --mode=execute valgrind $(VG_OPTS) $$p 2>vglog.$$p; \
- done;
- -rm -f vgcore.*
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * check-gst-renderer.c
- *
- * Gst Renderer unit tests
- *
- * Copyright (C) 2007 Nokia Corporation
- *
- */
-
-#include <glib.h>
-
-#include <check.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sqlite3.h>
-#include <gst/tag/tag.h>
-
-#include <libmafw/mafw.h>
-#include <checkmore.h>
-
-#include "config.h"
-
-#include "mafw-gst-renderer.h"
-#include "mafw-mock-playlist.h"
-#include "mafw-mock-pulseaudio.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "check-mafw-gstreamer-renderer"
-
-#define SAMPLE_AUDIO_CLIP "test.wav"
-#define SAMPLE_VIDEO_CLIP "test.avi"
-#define SAMPLE_IMAGE "testframe.png"
-
-/* Base timeout used when waiting for state transitions or execution of
- user function callbacks associated to each mafw-renderer function */
-#define DEFAULT_WAIT_TOUT 2000
-
-/* EOS timeout must be longer than the clip duration */
-#define EOS_TIMEOUT 7000
-
-SRunner *configure_tests(void);
-
-typedef struct {
- gint index;
- MafwPlayState state;
-} RendererInfo;
-
-typedef struct {
- gboolean called;
- gboolean error;
- gint err_code;
- gchar *err_msg;
- gint seek_position;
- gboolean error_signal_expected;
- GError *error_signal_received;
- const gchar *property_expected;
- GValue *property_received;
-} CallbackInfo;
-
-typedef struct {
- const gchar *expected_key;
- GValue *value;
-} MetadataChangedInfo;
-
-typedef struct {
- const gchar *expected;
- GValue *received;
-} PropertyChangedInfo;
-
-typedef struct {
- gboolean requested;
- gboolean received;
- gfloat value;
-} BufferingInfo;
-
-static gint wait_tout_val;
-
-/* Globals. */
-
-static MafwRenderer *g_gst_renderer = NULL;
-
-/* Error messages. */
-
-static const gchar *callback_err_msg = "Error received when %s: (%d) %s";
-static const gchar *callback_no_err_msg = "No error received when %s: (%d) %s";
-static const gchar *no_callback_msg = "We forgot to call the user callback";
-static const gchar *state_err_msg = "Call %s didn't change state to %s. " \
-"Current state is: %d";
-static const gchar *index_err_msg = "Actual index is (%d) instead of the " \
-"expected index (%d)";
-
-
-/*----------------------------------------------------------------------------
- Signal handlers
- ----------------------------------------------------------------------------*/
-
-
-static void error_cb(MafwRenderer *s, GQuark domain, gint code, gchar *msg,
- gpointer user_data)
-{
- CallbackInfo* c = (CallbackInfo*) user_data;
-
- /* "MafwExtension::error" signal handler */
- if (user_data == NULL || !c->error_signal_expected) {
- fail("Signal error received: (%d) %s", code, msg);
- } else {
- if (c->error_signal_received != NULL) {
- fail("Error received already initialized");
- } else {
- c->error_signal_received =
- g_error_new_literal(domain, code, msg);
- }
- }
-}
-
-static void state_changed_cb(MafwRenderer *s, MafwPlayState state,
- gpointer user_data)
-{
- /* "MafwRenderer::state-changed" signal handler */
- RendererInfo *si = (RendererInfo *) user_data;
- gchar *states[] = {"Stopped","Playing","Paused","Transitioning"};
-
- si->state = state;
- g_debug("state changed (%s) ---", states[state]);
-}
-
-static gboolean media_changed_called;
-
-static void media_changed_cb(MafwRenderer *s, gint index, gchar *objectid,
- gpointer user_data)
-{
- /* "MafwRenderer::media-changed" signal handler */
- RendererInfo *si = (RendererInfo *) user_data;
-
- si->index = index;
- g_debug("media changed (%d) ---", index);
- media_changed_called = TRUE;
-}
-static void playlist_changed_cb (MafwRenderer *self,
- GObject *playlist,
- gpointer user_data)
-{
- g_debug("playlist changed");
- fail_if(media_changed_called, "At first playlist-changed should be called");
-}
-
-static void metadata_changed_cb(MafwRenderer *self, const gchar *key,
- GValueArray *value, gpointer user_data)
-{
- MetadataChangedInfo *m = user_data;
-
- if (m->expected_key != NULL && strcmp(key, m->expected_key) == 0)
- {
- GValue *original;
-
- original = g_value_array_get_nth(value, 0);
-
- m->value = g_new0(GValue, 1);
- g_value_init(m->value, G_VALUE_TYPE(original));
- g_value_copy(original, m->value);
- }
-}
-
-static void property_changed_cb(MafwExtension *extension, const gchar *name,
- const GValue *value, gpointer user_data)
-{
- PropertyChangedInfo* p = (PropertyChangedInfo*) user_data;
- gchar *value_string;
-
- value_string = g_strdup_value_contents(value);
-
- g_debug("property_changed_cb: %s (%s)", name, value_string);
- g_free(value_string);
-
- if (p->expected != NULL &&
- strcmp(p->expected, name) == 0) {
- p->received = g_new0(GValue, 1);
- g_value_init(p->received, G_VALUE_TYPE(value));
- g_value_copy(value, p->received);
- }
-}
-
-static void buffering_info_cb(MafwRenderer *self, gfloat status,
- gpointer user_data)
-{
- BufferingInfo *b = user_data;
-
- if (b->requested) {
- b->received = TRUE;
- b->value = status;
- }
-}
-
-/*----------------------------------------------------------------------------
- Function callbacks
- ----------------------------------------------------------------------------*/
-
-
-static void status_cb(MafwRenderer* renderer, MafwPlaylist* playlist, guint index,
- MafwPlayState state,
- const gchar* object_id,
- gpointer user_data,
- const GError *error)
-{
- /* MafwRendererStatusCB */
- RendererInfo* s = (RendererInfo*) user_data;
- g_assert(s != NULL);
-
- if (error != NULL) {
- fail("Error received while trying to get renderer status: (%d) %s",
- error->code, error->message);
- }
- s->state = state;
-
-}
-
-static void playback_cb(MafwRenderer* renderer, gpointer user_data, const GError* error)
-{
- /* MafwRendererPlaybackCB:
-
- Called after mafw_renderer_play(), mafw_renderer_play_uri(),
- mafw_renderer_play_object(), mafw_renderer_stop(), mafw_renderer_pause(),
- mafw_renderer_resume(), mafw_renderer_next(), mafw_renderer_previous() or
- mafw_renderer_goto_index() has been called. */
- CallbackInfo* c = (CallbackInfo*) user_data;
- g_assert(c != NULL);
-
- c->called = TRUE;
- if (error != NULL) {
- c->error = TRUE;
- c->err_code = error->code;
- c->err_msg = g_strdup(error->message);
- }
-}
-
-static void seek_cb (MafwRenderer *self, gint position, gpointer user_data,
- const GError *error)
-{
- /* Called when seeking */
-
- CallbackInfo* c = (CallbackInfo*) user_data;
- g_assert(c != NULL);
-
- c->called = TRUE;
- c->seek_position = position;
- if (error != NULL) {
- c->error = TRUE;
- c->err_code = error->code;
- c->err_msg = g_strdup(error->message);
- }
-}
-
-static void get_position_cb(MafwRenderer *self, gint position,
- gpointer user_data, const GError *error)
-{
- CallbackInfo* c = (CallbackInfo*) user_data;
-
- g_debug("get position cb: %d", position);
-
- if (error != NULL) {
- c->error = TRUE;
- c->err_code = error->code;
- c->err_msg = g_strdup(error->message);
- }
- c->called = TRUE;
-}
-
-static void get_property_cb(MafwExtension *self,
- const gchar *name,
- GValue *value,
- gpointer user_data,
- const GError *error)
-{
- CallbackInfo* c = (CallbackInfo*) user_data;
- gchar *value_string;
-
- value_string = g_strdup_value_contents(value);
-
- g_debug("get property cb: %s (%s)", name, value_string);
- g_free(value_string);
-
- if (error != NULL) {
- c->error = TRUE;
- c->err_code = error->code;
- c->err_msg = g_strdup(error->message);
- }
-
- if (c->property_expected != NULL &&
- strcmp(c->property_expected, name) == 0) {
- c->property_received = g_new0(GValue, 1);
- g_value_init(c->property_received, G_VALUE_TYPE(value));
- g_value_copy(value, c->property_received);
-
- c->called = TRUE;
- }
-}
-
-/*----------------------------------------------------------------------------
- Helpers
- ----------------------------------------------------------------------------*/
-
-static gchar *get_sample_clip_path(const gchar *clip)
-{
- gchar *my_dir, *media;
-
- /* Makefile.am sets TESTS_DIR, required for VPATH builds (like make
- * distcheck). Otherwise assume we are running in-place. */
- my_dir = g_strdup(g_getenv("TESTS_DIR"));
- if (!my_dir)
- my_dir = g_get_current_dir();
- media = g_strconcat("file://", my_dir, G_DIR_SEPARATOR_S,
- "media" G_DIR_SEPARATOR_S, clip,
- NULL);
- g_free(my_dir);
- return media;
-}
-
-static gchar *get_sample_clip_objectid(const gchar *clip)
-{
- gchar *path = NULL;
- gchar *objectid = NULL;
-
- path = get_sample_clip_path(clip);
- objectid = mafw_source_create_objectid(path);
- g_free(path);
-
- return objectid;
-}
-
-static gboolean stop_wait_timeout(gpointer user_data)
-{
- gboolean *do_stop = (gboolean *) user_data;
- g_debug("stop wait timeout");
- *do_stop = TRUE;
-
- return FALSE;
-}
-
-static gboolean wait_until_timeout_finishes(guint millis)
-{
- guint timeout = 0;
- gboolean stop_wait = FALSE;
- gboolean result = FALSE;
-
- g_debug("Init wait_");
- /* We'll wait a limitted ammount of time */
- timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
- while(!stop_wait) {
- result= g_main_context_iteration(NULL, TRUE);
- }
-
- g_debug("End wait_");
- return TRUE;
-}
-
-static gboolean wait_for_state(RendererInfo *renderer_info,
- MafwPlayState expected_state, guint millis)
-{
- guint timeout = 0;
- gboolean stop_wait = FALSE;
-
- g_debug("Init wait for state");
- /* We'll wait a limitted ammount of time */
- timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
-
- while(renderer_info->state != expected_state && !stop_wait) {
- g_main_context_iteration(NULL, TRUE);
- }
-
- if (!stop_wait) {
- g_source_remove(timeout);
- }
-
- g_debug("End wait for state");
- return (renderer_info->state == expected_state);
-}
-
-static gboolean wait_for_callback(CallbackInfo *callback, guint millis)
-{
- guint timeout = 0;
- gboolean stop_wait = FALSE;
-
- g_debug("Init wait for callback");
- /* We'll wait a limitted ammount of time */
- timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
-
- while (callback->called == FALSE && !stop_wait) {
- g_main_context_iteration(NULL, TRUE);
- }
- if (!stop_wait) {
- g_source_remove(timeout);
- }
- g_debug("End wait for callback");
- return callback->called;
-}
-
-static gboolean wait_for_metadata(MetadataChangedInfo *callback, guint millis)
-{
- guint timeout = 0;
- gboolean stop_wait = FALSE;
-
- g_debug("Init wait for metadata");
- /* We'll wait a limitted ammount of time */
- timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
-
- while (callback->value == NULL && !stop_wait) {
- g_main_context_iteration(NULL, TRUE);
- }
- if (!stop_wait) {
- g_source_remove(timeout);
- }
- g_debug("End wait for metadata");
- return callback->value != NULL;
-}
-
-static gboolean wait_for_property(PropertyChangedInfo *callback, guint millis)
-{
- guint timeout = 0;
- gboolean stop_wait = FALSE;
-
- g_debug("Init wait for property changed");
- /* We'll wait a limitted ammount of time */
- timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
-
- while (callback->received == NULL && !stop_wait) {
- g_main_context_iteration(NULL, TRUE);
- }
- if (!stop_wait) {
- g_source_remove(timeout);
- }
- g_debug("End wait for callback");
- return callback->received != NULL;
-}
-
-static gboolean wait_for_buffering(BufferingInfo *callback, guint millis)
-{
- guint timeout = 0;
- gboolean stop_wait = FALSE;
-
- g_debug("Init wait for buffering info");
- /* We'll wait a limitted ammount of time */
- timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait);
-
- while (!callback->received && !stop_wait) {
- g_main_context_iteration(NULL, TRUE);
- }
- if (!stop_wait) {
- g_source_remove(timeout);
- }
- g_debug("End wait for buffering info");
- return callback->received;
-}
-
-static void reset_callback_info(CallbackInfo *callback_info)
-{
- if (callback_info->err_msg != NULL)
- g_free(callback_info->err_msg);
-
- callback_info->err_msg = NULL;
- callback_info->called = FALSE;
- callback_info->error = FALSE;
- callback_info->seek_position = 0;
- callback_info->error_signal_expected = FALSE;
- if (callback_info->error_signal_received != NULL) {
- g_error_free(callback_info->error_signal_received);
- callback_info->error_signal_received = NULL;
- }
- callback_info->property_expected = NULL;
- if (callback_info->property_received != NULL) {
- g_value_unset(callback_info->property_received);
- callback_info->property_received = NULL;
- }
-}
-
-/*----------------------------------------------------------------------------
- Fixtures
- ----------------------------------------------------------------------------*/
-
-static void fx_setup_dummy_gst_renderer(void)
-{
- MafwRegistry *registry;
-
- /* Setup GLib */
- g_type_init();
-
- /* Create a gst renderer instance */
- registry = MAFW_REGISTRY(mafw_registry_get_instance());
- fail_if(registry == NULL,
- "Error: cannot get MAFW registry");
-
- g_gst_renderer = MAFW_RENDERER(mafw_gst_renderer_new(registry));
- fail_if(!MAFW_IS_GST_RENDERER(g_gst_renderer),
- "Could not create gst renderer instance");
-}
-
-static void fx_teardown_dummy_gst_renderer(void)
-{
- g_object_unref(g_gst_renderer);
-}
-
-/*----------------------------------------------------------------------------
- Mockups
- ----------------------------------------------------------------------------*/
-
-/* GStreamer mock */
-
-GstElement * gst_element_factory_make(const gchar * factoryname,
- const gchar * name)
-{
- GstElementFactory *factory;
- GstElement *element;
- const gchar *use_factoryname;
-
- g_return_val_if_fail(factoryname != NULL, NULL);
-
- /* For testing, use playbin instead of playbin2 */
- if (g_ascii_strcasecmp(factoryname, "playbin2") == 0)
- use_factoryname = "playbin";
- else
- use_factoryname = factoryname;
-
- GST_LOG("gstelementfactory: make \"%s\" \"%s\"",
- use_factoryname, GST_STR_NULL (name));
-
- factory = gst_element_factory_find(use_factoryname);
- if (factory == NULL) {
- /* No factory */
- GST_INFO("no such element factory \"%s\"!", use_factoryname);
- return NULL;
- }
-
- GST_LOG_OBJECT(factory, "found factory %p", factory);
- if (g_ascii_strcasecmp(use_factoryname, "pulsesink") == 0) {
- element = gst_element_factory_make("fakesink", "pulsesink");
- g_object_set(G_OBJECT(element), "sync", TRUE, NULL);
- } else if (g_ascii_strcasecmp(use_factoryname, "xvimagesink") == 0) {
- element = gst_element_factory_make("fakesink", "xvimagesink");
- g_object_set(G_OBJECT(element), "sync", TRUE, NULL);
- } else {
- element = gst_element_factory_create(factory, name);
- }
- gst_object_unref(factory);
-
- if (element == NULL) {
- /* Create failed */
- GST_INFO_OBJECT(factory, "couldn't create instance!");
- return NULL;
- }
-
- GST_LOG("gstelementfactory: make \"%s\" \"%s\"",use_factoryname,
- GST_STR_NULL(name));
-
- /* Playbin will use fake renderer */
- if (g_ascii_strcasecmp(use_factoryname, "playbin") == 0) {
- GstElement *audiorenderer = gst_element_factory_make("fakesink",
- "audiorenderer");
-
- g_object_set(G_OBJECT(audiorenderer), "sync", TRUE, NULL);
- g_object_set(G_OBJECT(element),
- "audio-sink",
- audiorenderer,
- NULL);
- g_object_set(G_OBJECT(element),
- "video-sink",
- audiorenderer,
- NULL);
- }
-
- return element;
-}
-
-
-/*----------------------------------------------------------------------------
- Test cases
- ----------------------------------------------------------------------------*/
-
-START_TEST(test_basic_playback)
-{
- RendererInfo s;
- CallbackInfo c;
- MetadataChangedInfo m;
- GstBus *bus = NULL;
- GstMessage *message = NULL;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- m.expected_key = NULL;
- m.value = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "metadata-changed",
- G_CALLBACK(metadata_changed_cb),
- &m);
-
- /* --- Get initial status --- */
-
- reset_callback_info(&c);
-
- g_debug("get status...");
- mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
-
- /* --- Play --- */
-
- reset_callback_info(&c);
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- /* No media item has been set so, we should get an error */
- if (c.error == FALSE)
- fail("Play of unset media did not return an error");
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- gchar *objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
-
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Transitioning",
- s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- g_free(objectid);
-
- /* --- Get position --- */
-
- reset_callback_info(&c);
-
- mafw_renderer_get_position(g_gst_renderer, get_position_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "get_position", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Duration emission --- */
-
- m.expected_key = MAFW_METADATA_KEY_DURATION;
-
- bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus;
- fail_if(bus == NULL, "No GstBus");
-
- message = gst_message_new_duration(NULL, GST_FORMAT_TIME,
- 5 * GST_SECOND);
- gst_bus_post(bus, message);
-
- if (wait_for_metadata(&m, wait_tout_val) == FALSE) {
- fail("Expected " MAFW_METADATA_KEY_DURATION
- ", but not received");
- }
-
- fail_if(m.value == NULL, "Metadata " MAFW_METADATA_KEY_DURATION
- " not received");
-
- g_value_unset(m.value);
- g_free(m.value);
- m.value = NULL;
- m.expected_key = NULL;
-
- /* --- Pause --- */
-
- reset_callback_info(&c);
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_pause", "Paused", s.state);
- }
-
- /* --- Resume --- */
-
- reset_callback_info(&c);
-
- g_debug("resume...");
- mafw_renderer_resume(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "resuming", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_resume", "Playing", s.state);
- }
-
- /* --- Stop --- */
-
- reset_callback_info(&c);
-
- g_debug("stop...");
- mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "stopping", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state);
- }
-
-}
-END_TEST
-
-START_TEST(test_playlist_playback)
-{
- MafwPlaylist *playlist = NULL;
- gint i = 0;
- RendererInfo s = {0, };
- CallbackInfo c = {0, };
- gchar *cur_item_oid = NULL;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
-
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "playlist-changed",
- G_CALLBACK(playlist_changed_cb),
- NULL);
-
- /* --- Create and assign a playlist --- */
-
- g_debug("assign playlist...");
- playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
- cur_item_oid =
- get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- for (i=0; i<10; i++) {
- mafw_playlist_insert_item(
- playlist, i, cur_item_oid, NULL);
- }
- g_free(cur_item_oid);
- cur_item_oid = get_sample_clip_objectid("unexisting.wav");
- mafw_playlist_insert_item(playlist, 9, cur_item_oid, NULL);
- g_free(cur_item_oid);
-
- media_changed_called = FALSE;
- if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, NULL))
- {
- fail("Assign playlist failed");
- }
-
- wait_for_state(&s, Stopped, wait_tout_val);
-
- /* --- Play --- */
-
- reset_callback_info(&c);
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Playing", s.state);
- }
-
- /* --- Stop --- */
-
- reset_callback_info(&c);
-
- g_debug("stop...");
- mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "stopping", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_stop", "Stopped", s.state);
- }
-
- /* --- Next --- */
-
- /* Get actual index */
-
- gint initial_index = s.index;
-
- for (i=0; i<3; i++) {
-
- reset_callback_info(&c);
-
- g_debug("move to next...");
- mafw_renderer_next(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to next", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* Check if the playlist index is correct */
- fail_if(s.index != initial_index + (i+1), index_err_msg, s.index,
- initial_index + (i+1));
- }
-
-
- /* --- Prev --- */
-
- /* Get actual index */
- initial_index = s.index;
-
- for (i=0; i<3; i++) {
-
- reset_callback_info(&c);
-
- g_debug("move to prev...");
- mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to prev", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* Check if the playlist index is correct */
- fail_if(s.index != initial_index - (i+1), index_err_msg, s.index,
- initial_index - (i+1));
- }
-
- /* Check if renderer remains in Stopped state after some Prev operations */
- fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state "
- "after doing prev. The actual state is %s and must be %s",
- s.state, "Stopped");
-
- /* --- Stop --- */
-
- reset_callback_info(&c);
-
- g_debug("stop...");
- mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "stopping playback",
- c.err_code, c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg,"mafw_renderer_stop","Stopped", s.state);
- }
-
- /* --- Go to index in Stopped state --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 3...");
- mafw_renderer_goto_index(g_gst_renderer, 3, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "going to index 3", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* Check if the playlist index is correct */
- fail_if(s.index != 3, index_err_msg, s.index, 3);
-
- /* Check if renderer remains in Stopped state after running go to index */
- fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state "
- "after running go to index. The actual state is %s and must be"
- " %s", s.state, "Stopped");
-
- /* --- Play (playlist index is 3) --- */
-
- reset_callback_info(&c);
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Playing", s.state);
- }
-
- /* --- Goto index in Playing state --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 5...");
- mafw_renderer_goto_index(g_gst_renderer, 5, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "going to index", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_goto_index", "Playing", s.state);
- }
-
- /* Check if the index if correct */
- fail_if(s.index != 5, index_err_msg, s.index, 5);
-
- /* Check if renderer remains in Playing state after running go to index */
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail("Gst renderer didn't remain in Playing state after running "
- "go to index. The actual state is %s and must be %s",
- s.state, "Playing");
- }
-
- /* --- Goto an invalid index --- */
-
- reset_callback_info(&c);
-
- g_debug("goto the invalid index 20...");
- mafw_renderer_goto_index(g_gst_renderer, 20, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error == FALSE)
- fail("Error not received when we go to an incorrect"
- "index");
- } else {
- fail(no_callback_msg);
- }
-
- /* Check if the previous index (5) remains after an incorrect go to
- index request */
- fail_if(s.index != 5, index_err_msg, 5, s.index);
-
- reset_callback_info(&c);
-
- /* --- Reassigning playlist --- */
-
- media_changed_called = FALSE;
- if (!mafw_renderer_assign_playlist(g_gst_renderer,
- g_object_ref(playlist), NULL))
- {
- fail("Assign playlist failed");
- }
-
- wait_for_state(&s, Stopped, wait_tout_val);
-
- /* --- Go to index with invalid media --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 9...");
- mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "going to index 9", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* Check if the playlist index is correct */
- fail_if(s.index != 9, index_err_msg, s.index, 9);
-
- /* Check if renderer remains in Stopped state after running go
- * to index */
- fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped "
- "state after running go to index. The actual state is %d and "
- "must be %s", s.state, "Stopped");
-
- /* --- Play (playlist index is 9) --- */
-
- reset_callback_info(&c);
-
- c.error_signal_expected = TRUE;
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Transitioning",
- s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Playing", s.state);
- }
-
- fail_if(c.error_signal_received == NULL ||
- !g_error_matches(c.error_signal_received, MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_INVALID_URI),
- "No error received or incorrect one");
-
- if (c.error_signal_received != NULL) {
- g_error_free(c.error_signal_received);
- c.error_signal_received = NULL;
- }
- c.error_signal_expected = FALSE;
-
- /* --- Stop --- */
-
- reset_callback_info(&c);
-
- g_debug("stop...");
- mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "stopping playback",
- c.err_code, c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg,"mafw_renderer_stop","Stopped", s.state);
- }
-
- /* --- Remove last media --- */
-
- mafw_playlist_remove_item(playlist, 10, NULL);
-
- /* --- Go to index with invalid media --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 9...");
- mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "going to index 9", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* Check if the playlist index is correct */
- fail_if(s.index != 9, index_err_msg, s.index, 9);
-
- /* Check if renderer remains in Stopped state after running go
- * to index */
- fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped "
- "state after running go to index. The actual state is %d and "
- "must be %s", s.state, "Stopped");
-
- /* --- Play (playlist index is 9) --- */
-
- reset_callback_info(&c);
-
- c.error_signal_expected = TRUE;
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Transitioning",
- s.state);
- }
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Stopped", s.state);
- }
-
- fail_if(c.error_signal_received == NULL ||
- !g_error_matches(c.error_signal_received, MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_INVALID_URI),
- "No error received or incorrect one");
-
- if (c.error_signal_received != NULL) {
- g_error_free(c.error_signal_received);
- c.error_signal_received = NULL;
- }
- c.error_signal_expected = FALSE;
-
- /* --- Play incorrect object --- */
-
- reset_callback_info(&c);
-
- c.error_signal_expected = TRUE;
-
- gchar *objectid = get_sample_clip_objectid("unexisting.wav");
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning",
- s.state);
- }
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Stopped",
- s.state);
- }
-
- fail_if(c.error_signal_received == NULL ||
- !g_error_matches(c.error_signal_received, MAFW_RENDERER_ERROR,
- MAFW_RENDERER_ERROR_INVALID_URI),
- "No error received or incorrect one");
-
- if (c.error_signal_received != NULL) {
- g_error_free(c.error_signal_received);
- c.error_signal_received = NULL;
- }
- c.error_signal_expected = FALSE;
-
- g_free(objectid);
-
-}
-END_TEST
-
-
-START_TEST(test_repeat_mode_playback)
-{
- MafwPlaylist *playlist = NULL;
- gint i = 0;
- RendererInfo s = {0, };;
- CallbackInfo c = {0, };;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
-
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "playlist-changed",
- G_CALLBACK(playlist_changed_cb),
- NULL);
-
- /* --- Create playlist --- */
-
- playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
- for (i=0; i<10; i++) {
- gchar *cur_item_oid =
- get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- mafw_playlist_insert_item(
- playlist, i, cur_item_oid, NULL);
- g_free(cur_item_oid);
- }
-
- /* Set repeat mode */
- mafw_playlist_set_repeat(playlist, TRUE);
-
- /* --- Assign playlist --- */
-
- g_debug("assign playlist...");
- media_changed_called = FALSE;
- if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, NULL))
- {
- fail("Assign playlist failed");
- }
-
- wait_for_state(&s, Stopped, wait_tout_val);
-
- /* --- Play --- */
-
- reset_callback_info(&c);
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Playing", s.state);
- }
-
- /* --- Go to index --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 9...");
- /* go to the end of the playlist */
- mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "going to index 9", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* check if the movement was successful */
- fail_if(s.index != 9, index_err_msg, 9, s.index);
-
- /* --- Stop --- */
-
- reset_callback_info(&c);
-
- g_debug("stop...");
- mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "stopping playback", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_stop", "Stopped", s.state);
- }
-
- /* --- Next --- */
-
- reset_callback_info(&c);
-
- g_debug("next...");
- /* The actual index is 9 */
- mafw_renderer_next(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to next", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* check if the movement was successful */
- fail_if(s.index != 0, index_err_msg, s.index, 0);
-
- /* Check if renderer remains in Stopped state after moving to next */
- fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state "
- "after doing next. The actual state is %s and must be %s",
- s.state, "Stopped");
-
- /* --- Prev --- */
-
- reset_callback_info(&c);
-
- g_debug("prev...");
- /* The actual index is 0 */
- mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to prev", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* check if the movement was successful */
- fail_if(s.index != 9, index_err_msg, s.index, 9);
-
- /* Check if renderer remains in Stopped state after moving to next */
- fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state "
- "after doing next. The actual state is %s and must be %s",
- s.state, "Stopped");
-}
-END_TEST
-
-
-START_TEST(test_gst_renderer_mode)
-{
- MafwPlaylist *playlist = NULL;
- MafwGstRenderer *renderer = NULL;
- MafwGstRendererPlaybackMode play_mode;
- gchar *objectid = NULL;
- gint i = 0;
- RendererInfo s = {0, };;
- CallbackInfo c = {0, };;
- gchar *modes[] = {"MAFW_GST_RENDERER_MODE_PLAYLIST",
- "MAFW_GST_RENDERER_MODE_STANDALONE"};
-
- renderer = MAFW_GST_RENDERER(g_gst_renderer);
-
- /* Initiliaze callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
-
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "playlist-changed",
- G_CALLBACK(playlist_changed_cb),
- NULL);
-
- /* --- Create playlist --- */
-
- playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
- for (i=0; i<10; i++) {
- gchar *cur_item_oid =
- get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- mafw_playlist_insert_item(
- playlist, i, cur_item_oid, NULL);
- g_free(cur_item_oid);
- }
-
- /* --- Assign playlist --- */
-
- g_debug("assign playlist...");
- media_changed_called = FALSE;
- if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, NULL))
- {
- fail("Assign playlist failed");
- }
-
- wait_for_state(&s, Stopped, wait_tout_val);
-
- /* --- Play --- */
-
- reset_callback_info(&c);
-
- g_debug("play...");
-
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Transitioning", s.state);
- }
-
- /* Check that renderer is playing a playlist */
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Playing", s.state);
- }
- play_mode = mafw_gst_renderer_get_playback_mode(renderer);
- fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST,
- "Incorrect value of playback_mode: %s", modes[play_mode]);
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- g_debug("play_object... %s",objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
- g_free(objectid);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Transitioning",
- s.state);
- }
-
- /* Check that renderer is playing an object */
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- play_mode = mafw_gst_renderer_get_playback_mode(renderer);
- fail_if(play_mode != MAFW_GST_RENDERER_MODE_STANDALONE,
- "Incorrect value of playback_mode: %s", modes[play_mode]);
-
- /* Wait EOS_TIMEOUT to ensure that the play_object has finished */
- wait_until_timeout_finishes(EOS_TIMEOUT);
-
- /* Check that after playing the object, renderer returns to the playlist
- playback */
- play_mode = mafw_gst_renderer_get_playback_mode(renderer);
- fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST,
- "Incorrect value of playback_mode: %s", modes[play_mode]);
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
- g_free(objectid);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Transitioning",
- s.state);
- }
-
- /* Check that renderer is playing an object */
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
- play_mode = mafw_gst_renderer_get_playback_mode(renderer);
- fail_if(play_mode != MAFW_GST_RENDERER_MODE_STANDALONE,
- "Incorrect value of playback_mode: %s", modes[play_mode]);
-
-
- /* --- Move to next when renderer is playing an object --- */
-
- reset_callback_info(&c);
-
- g_debug("next...");
- mafw_renderer_next(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to next", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* Check that "next" function finishes the object playback and returns
- to the playlist playback */
- play_mode = mafw_gst_renderer_get_playback_mode(renderer);
- fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST,
- "Incorrect value of playback_mode: %s", modes[play_mode]);
-
- /* Check that renderer is still in Playing state */
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- /* --- Stop --- */
-
- reset_callback_info(&c);
-
- g_debug("stop...");
- mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "stopping", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state);
- }
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Transitioning",
- s.state);
- }
-
- /* Check that renderer is playing an object */
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
- play_mode = mafw_gst_renderer_get_playback_mode(renderer);
- fail_if(play_mode != MAFW_GST_RENDERER_MODE_STANDALONE,
- "Incorrect value of playback_mode: %s", modes[play_mode]);
-
- /* Wait EOS_TIMEOUT to ensure that object playback finishes */
- wait_until_timeout_finishes(EOS_TIMEOUT);
-
- /* Check if renderer is in playlist mode and the renderer state is the state before
- playing the object */
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state);
- }
- play_mode = mafw_gst_renderer_get_playback_mode(renderer);
- fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST,
- "Incorrect value of playback_mode: %s", modes[play_mode]);
-
- g_free(objectid);
-}
-END_TEST
-
-#define MOCK_SOURCE(o) \
- (G_TYPE_CHECK_INSTANCE_CAST((o), \
- mock_source_get_type(), \
- MockSource))
-
-typedef struct {
- MafwSourceClass parent;
-} MockSourceClass;
-
-typedef struct {
- MafwSource parent;
-
-
-} MockSource;
-
-GType mock_source_get_type(void);
-GObject* mock_source_new(void);
-
-G_DEFINE_TYPE(MockSource, mock_source, MAFW_TYPE_SOURCE);
-
-static GHashTable *get_md_ht; /* Metadata hash-table for the metadata result */
-static GError *get_md_err; /* Error value for the metadata result */
-static gboolean set_mdata_called; /* Whether set_metadata was called or not */
-static gboolean get_mdata_called; /* Whether get_metadata was called or not */
-static gint reference_pcount; /* Reference playcount, what should come in set_metadata */
-static gboolean set_for_playcount; /* TRUE, when the set_metadata is called to modify the playcount */
-static gboolean set_for_lastplayed; /* TRUE, when the set_metadata is called to modify the last-played */
-
-static void get_metadata(MafwSource *self,
- const gchar *object_id,
- const gchar *const *metadata,
- MafwSourceMetadataResultCb callback,
- gpointer user_data)
-{
- get_mdata_called = TRUE;
- fail_if(strcmp(object_id, "mocksource::test"));
- callback(self, object_id, get_md_ht, user_data, get_md_err);
-}
-
-static void set_metadata(MafwSource *self, const gchar *object_id,
- GHashTable *metadata,
- MafwSourceMetadataSetCb callback,
- gpointer user_data)
-{
- GValue *curval;
- gint htsize = 0;
-
- if (set_for_playcount)
- htsize++;
- if (set_for_lastplayed)
- htsize++;
- fail_if(strcmp(object_id, "mocksource::test"));
- fail_if(!metadata);
- fail_if(g_hash_table_size(metadata) != htsize, "Hash table size: %d vs %d", g_hash_table_size(metadata), htsize);
- if (set_for_playcount)
- {
- curval = mafw_metadata_first(metadata,
- MAFW_METADATA_KEY_PLAY_COUNT);
- fail_if(!curval);
- fail_if(g_value_get_int(curval) != reference_pcount);
- }
- if (set_for_lastplayed)
- {
- curval = mafw_metadata_first(metadata,
- MAFW_METADATA_KEY_LAST_PLAYED);
- fail_if(!curval);
- fail_if(!G_VALUE_HOLDS(curval, G_TYPE_LONG));
- }
- set_mdata_called = TRUE;
-}
-
-static void mock_source_class_init(MockSourceClass *klass)
-{
- MafwSourceClass *sclass = MAFW_SOURCE_CLASS(klass);
-
- sclass->get_metadata = get_metadata;
- sclass->set_metadata = set_metadata;
-
-}
-
-static void mock_source_init(MockSource *source)
-{
- /* NOP */
-}
-
-GObject* mock_source_new(void)
-{
- GObject* object;
- object = g_object_new(mock_source_get_type(),
- "plugin", "mockland",
- "uuid", "mocksource",
- "name", "mocksource",
- NULL);
- return object;
-}
-
-
-START_TEST(test_update_stats)
-{
- MafwGstRenderer *renderer = NULL;
- MafwSource *src;
- MafwRegistry *registry;
-
- registry = MAFW_REGISTRY(mafw_registry_get_instance());
- fail_if(registry == NULL,
- "Error: cannot get MAFW registry");
-
-
- renderer = MAFW_GST_RENDERER(g_gst_renderer);
- src = MAFW_SOURCE(mock_source_new());
-
- mafw_registry_add_extension(registry, MAFW_EXTENSION(src));
-
- /* Error on get_mdata_cb*/
- set_for_playcount = FALSE;
- set_for_lastplayed = FALSE;
- get_md_err = NULL;
- g_set_error(&get_md_err, MAFW_SOURCE_ERROR,
- MAFW_SOURCE_ERROR_INVALID_OBJECT_ID,
- "Wrong object id mocksource::test");
- renderer->media->object_id = g_strdup("mocksource::test");
- mafw_gst_renderer_update_stats(renderer);
- g_error_free(get_md_err);
- fail_if(set_mdata_called);
- fail_if(!get_mdata_called);
-
- /* get_mdata ok, but HashTable is NULL */
- reference_pcount = 1;
- get_mdata_called = FALSE;
- set_for_lastplayed = TRUE;
- set_for_playcount = TRUE;
- get_md_err = NULL;
- mafw_gst_renderer_update_stats(renderer);
- fail_if(!set_mdata_called);
- fail_if(!get_mdata_called);
-
- /* get_mdata ok, but HashTable is empty */
- get_mdata_called = FALSE;
- set_mdata_called = FALSE;
- set_for_lastplayed = TRUE;
- set_for_playcount = TRUE;
- get_md_ht = mafw_metadata_new();
- mafw_gst_renderer_update_stats(renderer);
- fail_if(!set_mdata_called);
- fail_if(!get_mdata_called);
-
- /* get_mdata ok, but HashTable has valid value */
- get_mdata_called = FALSE;
- set_mdata_called = FALSE;
- set_for_lastplayed = TRUE;
- set_for_playcount = TRUE;
- mafw_metadata_add_int(get_md_ht,
- MAFW_METADATA_KEY_PLAY_COUNT,
- 1);
- reference_pcount = 2;
- mafw_gst_renderer_update_stats(renderer);
- fail_if(!set_mdata_called);
- fail_if(!get_mdata_called);
-}
-END_TEST
-
-START_TEST(test_play_state)
-{
- MafwPlaylist *playlist = NULL;
- gint i = 0;
- RendererInfo s = {0, };;
- CallbackInfo c = {0, };;
- gchar *objectid = NULL;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
-
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "playlist-changed",
- G_CALLBACK(playlist_changed_cb),
- NULL);
-
- /* --- Get initial status --- */
-
- reset_callback_info(&c);
-
- g_debug("get status...");
- mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- if (wait_for_state(&s, Stopped, 3000) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Stop",
- s.state);
- }
-
- g_free(objectid);
-
-
- /* --- Create and assign a playlist --- */
-
- g_debug("assign playlist...");
- playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
- for (i=0; i<10; i++) {
- gchar *cur_item_oid =
- get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- mafw_playlist_insert_item(
- playlist, i, cur_item_oid, NULL);
- g_free(cur_item_oid);
- }
- mafw_playlist_set_repeat(playlist, FALSE);
-
- media_changed_called = FALSE;
- if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist,
- NULL))
- {
- fail("Assign playlist failed");
- }
-
- wait_for_state(&s, Stopped, wait_tout_val);
-
- /* --- Play --- */
-
- reset_callback_info(&c);
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail("Play after assigning playlist failed");
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Playing",
- s.state);
- }
-
- /* --- Prev --- */
-
- reset_callback_info(&c);
-
- g_debug("move to prev...");
- mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to prev", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(s.index != 9, index_err_msg, s.index, 9);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_prev",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_prev", "Playing",
- s.state);
- }
-
- /* Removing last element */
-
- g_debug("removing last element...");
- fail_if(mafw_playlist_get_size(playlist, NULL) != 10,
- "Playlist should have 10 elements");
- mafw_playlist_remove_item(playlist, 9, NULL);
- fail_if(mafw_playlist_get_size(playlist, NULL) != 9,
- "Playlist should have 9 elements");
- fail_if(s.index != 8, index_err_msg, s.index, 8);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_playlist_remove_element",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_playlist_remove_element", "Playing",
- s.state);
- }
-
- /* --- Next --- */
-
- reset_callback_info(&c);
-
- g_debug("move to next...");
- mafw_renderer_next(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to next", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(s.index != 0, index_err_msg, s.index, 0);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_next",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_next", "Playing",
- s.state);
- }
-
- /* --- Go to index --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 8...");
- mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "going to index 8", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(s.index != 8, index_err_msg, s.index, 8);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_goto_index",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_goto_index", "Playing",
- s.state);
- }
-
- /* --- Seeking --- */
-
- reset_callback_info(&c);
-
- g_debug("seeking...");
- mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, 1,
- seek_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "seeking failed", c.err_code,
- c.err_msg);
- if (c.seek_position != 1) {
- fail("seeking failed");
- }
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Waiting EOS --- */
-
- if (wait_for_state(&s, Stopped, 2000) == FALSE) {
- fail(state_err_msg, "EOS", "Stop",
- s.state);
- }
-}
-END_TEST
-
-START_TEST(test_pause_state)
-{
- MafwPlaylist *playlist = NULL;
- gint i = 0;
- RendererInfo s = {0, };;
- CallbackInfo c = {0, };;
- gchar *objectid = NULL;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
-
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "playlist-changed",
- G_CALLBACK(playlist_changed_cb),
- NULL);
-
- /* --- Get initial status --- */
-
- reset_callback_info(&c);
-
- g_debug("get status...");
- mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
-
- /* --- Create and assign a playlist --- */
-
- g_debug("assign playlist...");
- playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
- for (i=0; i<10; i++) {
- gchar *cur_item_oid =
- get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- mafw_playlist_insert_item(
- playlist, i, cur_item_oid, NULL);
- g_free(cur_item_oid);
- }
- mafw_playlist_set_repeat(playlist, FALSE);
-
- media_changed_called = FALSE;
- if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist,
- NULL))
- {
- fail("Assign playlist failed");
- }
-
- wait_for_state(&s, Stopped, wait_tout_val);
-
- /* --- Play --- */
-
- reset_callback_info(&c);
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail("Play failed");
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play",
- "Transitioning", s.state);
- }
-
- /* Testing pause in transitioning */
-
- reset_callback_info(&c);
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* Testing resume in transitioning */
-
- reset_callback_info(&c);
-
- g_debug("resume...");
- mafw_renderer_resume(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "resuming", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- reset_callback_info(&c);
-
- /* Testing resume without having paused in transitioning */
-
- reset_callback_info(&c);
-
- g_debug("resume...");
- mafw_renderer_resume(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (!c.error)
- fail(callback_no_err_msg, "resuming", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- reset_callback_info(&c);
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_pause", "Paused",
- s.state);
- }
-
- /* --- Play object in pause --- */
-
- reset_callback_info(&c);
-
- objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- reset_callback_info(&c);
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_pause", "Paused",
- s.state);
- }
-
- g_free(objectid);
-
- /* --- Play --- */
-
- reset_callback_info(&c);
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail("Play failed");
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play",
- "Transitioning", s.state);
- }
-
- reset_callback_info(&c);
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_pause", "Paused",
- s.state);
- }
-
- /* --- Prev --- */
-
- reset_callback_info(&c);
-
- g_debug("move to prev...");
- mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to prev", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* Check if the playlist index is correct */
- fail_if(s.index != 9, index_err_msg, s.index, 9);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_prev",
- "Transitioning", s.state);
- }
-
- reset_callback_info(&c);
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_prev", "Playing",
- s.state);
- }
-
- /* Removing last element */
-
- g_debug("removing last element...");
- fail_if(mafw_playlist_get_size(playlist, NULL) != 10,
- "Playlist should have 10 elements");
- mafw_playlist_remove_item(playlist, 9, NULL);
- fail_if(mafw_playlist_get_size(playlist, NULL) != 9,
- "Playlist should have 9 elements");
- fail_if(s.index != 8, index_err_msg, s.index, 8);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_playlist_remove_item",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_playlist_remove_item", "Playing",
- s.state);
- }
-
- reset_callback_info(&c);
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_playlist_remove_item", "Playing",
- s.state);
- }
-
- /* --- Next --- */
-
- reset_callback_info(&c);
-
- g_debug("move to next...");
- mafw_renderer_next(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to next", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* Check if the playlist index is correct */
- fail_if(s.index != 0, index_err_msg, s.index, 0);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_next",
- "Transitioning", s.state);
- }
-
- reset_callback_info(&c);
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_next", "Playing",
- s.state);
- }
-
- /* --- Go to index --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 8...");
- mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "going to index 8", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* Check if the playlist index is correct */
- fail_if(s.index != 8, index_err_msg, s.index, 8);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_goto_index",
- "Transitioning", s.state);
- }
-
- reset_callback_info(&c);
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_goto_index", "Playing",
- s.state);
- }
-
- /* --- Seeking --- */
-
- reset_callback_info(&c);
-
- mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, 1,
- seek_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "seeking", c.err_code,
- c.err_msg);
- if (c.seek_position != 1) {
- fail("seeking failed");
- }
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Stop --- */
-
- reset_callback_info(&c);
-
- g_debug("stop...");
- mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "stopping", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state);
- }
-}
-END_TEST
-
-START_TEST(test_stop_state)
-{
- MafwPlaylist *playlist = NULL;
- gint i = 0;
- RendererInfo s = {0, };;
- CallbackInfo c = {0, };;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
-
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "playlist-changed",
- G_CALLBACK(playlist_changed_cb),
- NULL);
-
- /* --- Get initial status --- */
-
- reset_callback_info(&c);
-
- g_debug("get status...");
- mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
-
- /* --- Prev --- */
-
- reset_callback_info(&c);
-
- g_debug("move to prev...");
- mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (!c.error)
- fail(callback_no_err_msg, "moving to prev", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Next --- */
-
- reset_callback_info(&c);
-
- g_debug("move to next...");
- mafw_renderer_next(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (!c.error)
- fail(callback_no_err_msg, "moving to next", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Go to index --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 8...");
- mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (!c.error)
- fail(callback_no_err_msg, "going to index 8",
- c.err_code, c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Create and assign a playlist --- */
-
- g_debug("assign playlist...");
- playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
- for (i=0; i<10; i++) {
- gchar *cur_item_oid =
- get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- mafw_playlist_insert_item(
- playlist, i, cur_item_oid, NULL);
- g_free(cur_item_oid);
- }
- mafw_playlist_set_repeat(playlist, FALSE);
-
- media_changed_called = FALSE;
- if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist,
- NULL))
- {
- fail("Assign playlist failed");
- }
-
- wait_for_state(&s, Stopped, wait_tout_val);
-
- /* Removing last element */
-
- g_debug("removing last element...");
- fail_if(mafw_playlist_get_size(playlist, NULL) != 10,
- "Playlist should have 10 elements");
- mafw_playlist_remove_item(playlist, 9, NULL);
- fail_if(mafw_playlist_get_size(playlist, NULL) != 9,
- "Playlist should have 9 elements");
-
- /* --- Go to index --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 9...");
- mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (!c.error)
- fail(callback_no_err_msg, "going to index 9",
- c.err_code, c.err_msg);
- } else {
- fail(no_callback_msg);
- }
- reset_callback_info(&c);
-}
-END_TEST
-
-START_TEST(test_transitioning_state)
-{
- MafwPlaylist *playlist = NULL;
- gint i = 0;
- RendererInfo s = {0, };;
- CallbackInfo c = {0, };;
- gchar *objectid = NULL;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
-
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "playlist-changed",
- G_CALLBACK(playlist_changed_cb),
- NULL);
-
- /* --- Get initial status --- */
-
- reset_callback_info(&c);
-
- g_debug("get status...");
- mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
-
- /* --- Create and assign a playlist --- */
-
- g_debug("assign playlist...");
- playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
- for (i=0; i<10; i++) {
- gchar *cur_item_oid =
- get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- mafw_playlist_insert_item(
- playlist, i, cur_item_oid, NULL);
- g_free(cur_item_oid);
- }
- mafw_playlist_set_repeat(playlist, FALSE);
-
- media_changed_called = FALSE;
- if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist,
- NULL))
- {
- fail("Assign playlist failed");
- }
-
- wait_for_state(&s, Stopped, wait_tout_val);
-
- /* --- Play --- */
-
- reset_callback_info(&c);
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail("Play after assigning playlist failed");
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play",
- "Transitioning", s.state);
- }
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- g_free(objectid);
-
-
- /* --- Prev --- */
-
- reset_callback_info(&c);
-
- g_debug("move to prev...");
- mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to prev", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(s.index != 9, index_err_msg, s.index, 9);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_prev",
- "Transitioning", s.state);
- }
-
- /* Removing last element */
-
- g_debug("removing last element...");
- fail_if(mafw_playlist_get_size(playlist, NULL) != 10,
- "Playlist should have 10 elements");
- mafw_playlist_remove_item(playlist, 9, NULL);
- fail_if(mafw_playlist_get_size(playlist, NULL) != 9,
- "Playlist should have 9 elements");
- fail_if(s.index != 8, index_err_msg, s.index, 8);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_playlist_remove_element",
- "Transitioning", s.state);
- }
-
- /* --- Next --- */
-
- reset_callback_info(&c);
-
- g_debug("move to next...");
- mafw_renderer_next(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to next", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(s.index != 0, index_err_msg, s.index, 0);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_next",
- "Transitioning", s.state);
- }
-
- /* --- Go to index --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 8...");
- mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "going to index 8", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(s.index != 8, index_err_msg, s.index, 8);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_goto_index",
- "Transitioning", s.state);
- }
-}
-END_TEST
-
-START_TEST(test_state_class)
-{
- MafwPlaylist *playlist = NULL;
- gint i = 0;
- RendererInfo s = {0, };;
- CallbackInfo c = {0, };;
- gchar *objectid = NULL;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
-
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "playlist-changed",
- G_CALLBACK(playlist_changed_cb),
- NULL);
-
- /* --- Get initial status --- */
-
- reset_callback_info(&c);
-
- g_debug("get status...");
- mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- /* --- Prev --- */
-
- reset_callback_info(&c);
-
- g_debug("move to prev...");
- mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (!c.error)
- fail(callback_no_err_msg, "moving to prev", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- /* --- Next --- */
-
- reset_callback_info(&c);
-
- g_debug("move to next...");
- mafw_renderer_next(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (!c.error)
- fail(callback_no_err_msg, "moving to next", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- /* --- Go to index --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 8...");
- mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (!c.error)
- fail(callback_err_msg, "going to index 8", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Create and assign a playlist --- */
-
- g_debug("assign playlist...");
- playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
- for (i=0; i<10; i++) {
- gchar *cur_item_oid =
- get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- mafw_playlist_insert_item(
- playlist, i, cur_item_oid, NULL);
- g_free(cur_item_oid);
- }
- mafw_playlist_set_repeat(playlist, FALSE);
-
- media_changed_called = FALSE;
- if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist,
- NULL))
- {
- fail("Assign playlist failed");
- }
-
- wait_for_state(&s, Stopped, wait_tout_val);
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- /* --- Next --- */
-
- reset_callback_info(&c);
-
- g_debug("move to next...");
- mafw_renderer_next(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to next", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(s.index != 1, index_err_msg, s.index, 1);
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_next", "Playing",
- s.state);
- }
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- /* --- Go to index --- */
-
- reset_callback_info(&c);
-
- g_debug("goto index 8...");
- mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "going to index 8", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(s.index != 8, index_err_msg, s.index, 8);
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_goto_index", "Playing",
- s.state);
- }
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- /* --- Prev --- */
-
- reset_callback_info(&c);
-
- g_debug("move to prev...");
- mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to prev", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(s.index != 7, index_err_msg, s.index, 7);
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_prev", "Playing",
- s.state);
- }
-
- /* --- Play --- */
-
- reset_callback_info(&c);
-
- g_debug("play...");
- mafw_renderer_play(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail("Play after assigning playlist failed");
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play", "Playing",
- s.state);
- }
-
- /* --- Prev --- */
-
- reset_callback_info(&c);
-
- g_debug("move to prev...");
- mafw_renderer_previous(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "moving to prev", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(s.index != 6, index_err_msg, s.index, 6);
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_prev",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_prev",
- "Transitioning", s.state);
- }
-
- /* --- Seeking --- */
-
- reset_callback_info(&c);
-
- g_debug("seeking...");
- mafw_renderer_set_position(g_gst_renderer, SeekRelative, 1,
- seek_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "seeking failed", c.err_code,
- c.err_msg);
- if (c.seek_position != 1) {
- fail("seeking failed");
- }
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Seeking --- */
-
- reset_callback_info(&c);
-
- g_debug("seeking...");
- mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, -1,
- seek_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "seeking failed", c.err_code,
- c.err_msg);
- if (c.seek_position != -1) {
- fail("seeking failed");
- }
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Seeking --- */
-
- reset_callback_info(&c);
-
- g_debug("seeking...");
- mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, 1,
- seek_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "seeking failed", c.err_code,
- c.err_msg);
- if (c.seek_position != 1) {
- fail("seeking failed");
- }
- } else {
- fail(no_callback_msg);
- }
-}
-END_TEST
-
-START_TEST(test_playlist_iterator)
-{
- MafwPlaylist *playlist = NULL;
- gint i = 0;
- CallbackInfo c = {0, };;
- MafwPlaylistIterator *iterator = NULL;
- GError *error = NULL;
- gint size;
- gint index;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error = FALSE;
- reset_callback_info(&c);
-
- /* --- Create and assign a playlist --- */
-
- g_debug("assign playlist...");
- playlist = MAFW_PLAYLIST(mafw_mock_playlist_new());
-
- iterator = mafw_playlist_iterator_new();
- mafw_playlist_iterator_initialize(iterator, playlist, &error);
- if (error != NULL) {
- fail("Error found: %s, %d, %s",
- g_quark_to_string(error->domain),
- error->code, error->message);
- }
-
- for (i = 0; i < 3; i++) {
- gchar *cur_item_oid = NULL;
- cur_item_oid =
- get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- mafw_playlist_insert_item(playlist, 0, cur_item_oid, NULL);
- g_free(cur_item_oid);
- }
-
- size = mafw_playlist_iterator_get_size(iterator, NULL);
- fail_if(size != 3, "Playlist should have 3 elements and it has %d",
- size);
- index = mafw_playlist_iterator_get_current_index(iterator);
- fail_if(index != 2, "Index should be 2 and it is %d", index);
-
- mafw_playlist_move_item(playlist, 1, 2, NULL);
- index = mafw_playlist_iterator_get_current_index(iterator);
- fail_if(index != 1, "Index should be 1 and it is %d", index);
-
- mafw_playlist_move_item(playlist, 2, 1, NULL);
- index = mafw_playlist_iterator_get_current_index(iterator);
- fail_if(index != 2, "Index should be 2 and it is %d", index);
-
- mafw_playlist_move_item(playlist, 2, 1, NULL);
- index = mafw_playlist_iterator_get_current_index(iterator);
- fail_if(index != 1, "Index should be 1 and it is %d", index);
-
- mafw_playlist_remove_item(playlist, 0, &error);
- if (error != NULL) {
- fail("Error found: %s, %d, %s",
- g_quark_to_string(error->domain),
- error->code, error->message);
- }
-
- size = mafw_playlist_iterator_get_size(iterator, NULL);
- fail_if(size != 2, "Playlist should have 2 elements and it has %d",
- size);
- index = mafw_playlist_iterator_get_current_index(iterator);
- fail_if(index != 0, "Index should be 0 and it is %d", index);
-
- mafw_playlist_iterator_reset(iterator, NULL);
- index = mafw_playlist_iterator_get_current_index(iterator);
- fail_if(index != 0, "Index should be 0 and it is %d", index);
-
- mafw_playlist_remove_item(playlist, 0, &error);
- if (error != NULL) {
- fail("Error found: %s, %d, %s",
- g_quark_to_string(error->domain),
- error->code, error->message);
- }
-
- size = mafw_playlist_iterator_get_size(iterator, NULL);
- fail_if(size != 1, "Playlist should have 1 elements and it has %d",
- size);
- index = mafw_playlist_iterator_get_current_index(iterator);
- fail_if(index != 0, "Index should be 0 and it is %d", index);
-
- mafw_playlist_remove_item(playlist, 0, &error);
- if (error != NULL) {
- fail("Error found: %s, %d, %s",
- g_quark_to_string(error->domain),
- error->code, error->message);
- }
-
- size = mafw_playlist_iterator_get_size(iterator, NULL);
- fail_if(size != 0, "Playlist should have 0 elements and it has %d",
- size);
- index = mafw_playlist_iterator_get_current_index(iterator);
- fail_if(index != -1, "Index should be -1 and it is %d", index);
-
- g_object_unref(iterator);
-}
-END_TEST
-
-START_TEST(test_video)
-{
- RendererInfo s = {0, };;
- CallbackInfo c = {0, };;
- MetadataChangedInfo m;
- gchar *objectid = NULL;
- GstBus *bus = NULL;
- GstStructure *structure = NULL;
- GstMessage *message = NULL;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- m.expected_key = NULL;
- m.value = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
-
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "playlist-changed",
- G_CALLBACK(playlist_changed_cb),
- NULL);
- g_signal_connect(g_gst_renderer, "metadata-changed",
- G_CALLBACK(metadata_changed_cb),
- &m);
-
-#ifdef HAVE_GDKPIXBUF
- mafw_extension_set_property_boolean(
- MAFW_EXTENSION(g_gst_renderer),
- MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE,
- TRUE);
-#endif
-
- /* --- Get initial status --- */
-
- reset_callback_info(&c);
-
- g_debug("get status...");
- mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- objectid = get_sample_clip_objectid(SAMPLE_VIDEO_CLIP);
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- MAFW_GST_RENDERER(g_gst_renderer)->worker->xid = 0x1;
- bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus;
- fail_if(bus == NULL, "No GstBus");
-
- structure = gst_structure_new("prepare-xwindow-id", "width",
- G_TYPE_INT, 64, "height", G_TYPE_INT, 32,
- NULL);
- message = gst_message_new_element(NULL, structure);
- gst_bus_post(bus, message);
-
- /* --- Pause --- */
-
- reset_callback_info(&c);
-
- m.expected_key = MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI;
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_prev", "Playing",
- s.state);
- }
-
- if (wait_for_metadata(&m, wait_tout_val) == FALSE) {
- fail("Expected " MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI
- ", but not received");
- }
-
- fail_if(m.value == NULL, "Metadata "
- MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI " not received");
-
- g_value_unset(m.value);
- g_free(m.value);
- m.value = NULL;
- m.expected_key = NULL;
-
- /* --- Resume --- */
-
- reset_callback_info(&c);
-
- g_debug("resume...");
- mafw_renderer_resume(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "resuming", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- /* --- EOS --- */
-
- if (wait_for_state(&s, Stopped, 3000) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Stop",
- s.state);
- }
-
- g_free(objectid);
-}
-END_TEST
-
-START_TEST(test_media_art)
-{
- RendererInfo s = {0, };;
- CallbackInfo c = {0, };;
- MetadataChangedInfo m;
- gchar *objectid = NULL;
- GstBus *bus = NULL;
- GstMessage *message = NULL;
- GstTagList *list = NULL;
- GstBuffer *buffer = NULL;
- guchar *image = NULL;
- gchar *image_path = NULL;
- gsize image_length;
- GstCaps *caps = NULL;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- m.expected_key = NULL;
- m.value = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
-
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "media-changed",
- G_CALLBACK(media_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "playlist-changed",
- G_CALLBACK(playlist_changed_cb),
- NULL);
- g_signal_connect(g_gst_renderer, "metadata-changed",
- G_CALLBACK(metadata_changed_cb),
- &m);
-
- /* --- Get initial status --- */
-
- reset_callback_info(&c);
-
- g_debug("get status...");
- mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb,
- &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- /* --- Pause --- */
-
- reset_callback_info(&c);
-
- g_debug("pause...");
- mafw_renderer_pause(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "pausing", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_prev", "Playing",
- s.state);
- }
-
- /* Emit image */
-
- bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus;
- fail_if(bus == NULL, "No GstBus");
-
- m.expected_key = MAFW_METADATA_KEY_RENDERER_ART_URI;
-
- image_path = get_sample_clip_path(SAMPLE_IMAGE);
- fail_if(!g_file_get_contents(image_path + 7, (gchar **) &image,
- &image_length, NULL),
- "Could not load test image");
- g_free(image_path);
-
- buffer = gst_buffer_new();
- gst_buffer_set_data(buffer, image, image_length);
- caps = gst_caps_new_simple("image/png", "image-type",
- GST_TYPE_TAG_IMAGE_TYPE,
- GST_TAG_IMAGE_TYPE_FRONT_COVER, NULL);
- gst_buffer_set_caps(buffer, caps);
- gst_caps_unref(caps);
-
- list = gst_tag_list_new();
- gst_tag_list_add(list, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, buffer,
- NULL);
-
- message = gst_message_new_tag(NULL, list);
- gst_bus_post(bus, message);
-
- /* --- Resume --- */
-
- reset_callback_info(&c);
-
- g_debug("resume...");
- mafw_renderer_resume(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "resuming", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- if (wait_for_metadata(&m, wait_tout_val) == FALSE) {
- fail("Expected " MAFW_METADATA_KEY_RENDERER_ART_URI
- ", but not received");
- }
-
- fail_if(m.value == NULL, "Metadata "
- MAFW_METADATA_KEY_RENDERER_ART_URI " not received");
-
- g_value_unset(m.value);
- g_free(m.value);
- m.value = NULL;
- m.expected_key = NULL;
-
- /* --- EOS --- */
-
- if (wait_for_state(&s, Stopped, 3000) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Stop",
- s.state);
- }
-
- g_free(objectid);
-}
-END_TEST
-
-START_TEST(test_properties_management)
-{
- RendererInfo s;
- CallbackInfo c = {0, };;
- PropertyChangedInfo p;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
- p.expected = NULL;
- p.received = NULL;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "property-changed",
- G_CALLBACK(property_changed_cb),
- &p);
-
- /* Wait for the volume manager to be initialized */
-
- /* Volume */
-
- p.expected = MAFW_PROPERTY_RENDERER_VOLUME;
-
- if (!wait_for_property(&p, wait_tout_val)) {
- fail("No property %s received", p.expected);
- }
-
- fail_if(p.received == NULL, "No property %s received",
- p.expected);
- fail_if(p.received != NULL &&
- g_value_get_uint(p.received) != 48,
- "Property with value %d and %d expected",
- g_value_get_uint(p.received), 48);
-
- if (p.received != NULL) {
- g_value_unset(p.received);
- g_free(p.received);
- p.received = NULL;
- }
- p.expected = NULL;
-
- /* --- mute --- */
-
- reset_callback_info(&c);
-
- c.property_expected = MAFW_PROPERTY_RENDERER_MUTE;
-
- mafw_extension_set_property_boolean(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, TRUE);
-
- p.expected = MAFW_PROPERTY_RENDERER_MUTE;
-
-#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
- if (!wait_for_property(&p, wait_tout_val)) {
- fail("No property %s received", p.expected);
- }
-
- fail_if(p.received == NULL, "No property %s received",
- p.expected);
- fail_if(p.received != NULL &&
- g_value_get_boolean(p.received) != TRUE,
- "Property with value %d and %d expected",
- g_value_get_boolean(p.received), TRUE);
-#else
- if (wait_for_property(&p, wait_tout_val)) {
- fail("Property %s received and it should not have been",
- p.expected);
- }
-
- fail_if(p.received != NULL,
- "Property %s received and it should not have been",
- p.expected);
-#endif
-
- if (p.received != NULL) {
- g_value_unset(p.received);
- g_free(p.received);
- p.received = NULL;
- }
- p.expected = NULL;
-
- mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, get_property_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "get_property", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(c.property_received == NULL,
- "No property %s received and expected", c.property_expected);
-#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
- fail_if(c.property_received != NULL &&
- g_value_get_boolean(c.property_received) != TRUE,
- "Property with value %d and %d expected",
- g_value_get_boolean(c.property_received), TRUE);
-#else
- fail_if(c.property_received != NULL &&
- g_value_get_boolean(c.property_received) != FALSE,
- "Property with value %d and %d expected",
- g_value_get_boolean(c.property_received), FALSE);
-#endif
-
- /* --- xid --- */
-
- reset_callback_info(&c);
-
- c.property_expected = MAFW_PROPERTY_RENDERER_XID;
-
- mafw_extension_set_property_uint(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, 50);
-
- mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, get_property_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "get_property", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(c.property_received == NULL,
- "No property %s received and expected", c.property_expected);
- fail_if(c.property_received != NULL &&
- g_value_get_uint(c.property_received) != 50,
- "Property with value %d and %d expected",
- g_value_get_uint(c.property_received), 50);
-
- /* --- error policy --- */
-
- reset_callback_info(&c);
-
- c.property_expected = MAFW_PROPERTY_RENDERER_ERROR_POLICY;
-
- mafw_extension_set_property_uint(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, 1);
-
- mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, get_property_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "get_property", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(c.property_received == NULL,
- "No property %s received and expected", c.property_expected);
- fail_if(c.property_received != NULL &&
- g_value_get_uint(c.property_received) != 1,
- "Property with value %d and %d expected",
- g_value_get_uint(c.property_received), 1);
-
- /* --- autopaint --- */
-
- reset_callback_info(&c);
-
- c.property_expected = MAFW_PROPERTY_RENDERER_AUTOPAINT;
-
- mafw_extension_set_property_boolean(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, TRUE);
-
- mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, get_property_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "get_property", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(c.property_received == NULL,
- "No property %s received and expected", c.property_expected);
- fail_if(c.property_received != NULL &&
- g_value_get_boolean(c.property_received) != TRUE,
- "Property with value %d and %d expected",
- g_value_get_boolean(c.property_received), TRUE);
-
- /* --- colorkey --- */
-
- reset_callback_info(&c);
-
- c.property_expected = MAFW_PROPERTY_RENDERER_COLORKEY;
-
- mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, get_property_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "get_property", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(c.property_received == NULL,
- "No property %s received and expected", c.property_expected);
- fail_if(c.property_received != NULL &&
- g_value_get_int(c.property_received) != -1,
- "Property with value %d and %d expected",
- g_value_get_int(c.property_received), -1);
-
- /* --- current frame on pause --- */
-
- reset_callback_info(&c);
-
- c.property_expected = MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE;
-
- mafw_extension_set_property_boolean(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, TRUE);
-
- mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, get_property_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "get_property", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(c.property_received == NULL,
- "No property %s received and expected", c.property_expected);
- fail_if(c.property_received != NULL &&
- g_value_get_boolean(c.property_received) != TRUE,
- "Property with value %d and %d expected",
- g_value_get_boolean(c.property_received), TRUE);
-
- /* --- volume --- */
-
- p.expected = MAFW_PROPERTY_RENDERER_VOLUME;
-
- mafw_extension_set_property_uint(MAFW_EXTENSION(g_gst_renderer),
- p.expected, 50);
-
- if (!wait_for_property(&p, wait_tout_val)) {
- fail("No property %s received", p.expected);
- }
-
- fail_if(p.received == NULL, "No property %s received",
- p.expected);
- fail_if(p.received != NULL &&
- g_value_get_uint(p.received) != 50,
- "Property with value %d and %d expected",
- g_value_get_uint(p.received), 50);
-
- if (p.received != NULL) {
- g_value_unset(p.received);
- g_free(p.received);
- p.received = NULL;
- }
- p.expected = NULL;
-
- c.property_expected = MAFW_PROPERTY_RENDERER_VOLUME;
-
- mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer),
- c.property_expected, get_property_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "get_property", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- fail_if(c.property_received == NULL,
- "No property %s received and expected", c.property_expected);
- fail_if(c.property_received != NULL &&
- g_value_get_uint(c.property_received) != 50,
- "Property with value %d and %d expected",
- g_value_get_uint(c.property_received), 50);
-
-#ifndef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME
- /* Test reconnection to pulse */
-
- pa_context_disconnect(pa_context_get_instance());
-
- /* Wait for the volume manager to be reinitialized */
-
- /* Volume */
-
- p.expected = MAFW_PROPERTY_RENDERER_VOLUME;
-
- if (!wait_for_property(&p, wait_tout_val)) {
- fail("No property %s received", p.expected);
- }
-
- fail_if(p.received == NULL, "No property %s received",
- p.expected);
- fail_if(p.received != NULL &&
- g_value_get_uint(p.received) != 48,
- "Property with value %d and %d expected",
- g_value_get_uint(p.received), 48);
-
- if (p.received != NULL) {
- g_value_unset(p.received);
- g_free(p.received);
- p.received = NULL;
- }
- p.expected = NULL;
-
- reset_callback_info(&c);
-#endif
-}
-END_TEST
-
-START_TEST(test_buffering)
-{
- RendererInfo s;
- CallbackInfo c;
- BufferingInfo b;
- GstBus *bus = NULL;
- GstMessage *message = NULL;
-
- /* Initialize callback info */
- c.err_msg = NULL;
- c.error_signal_expected = FALSE;
- c.error_signal_received = NULL;
- c.property_expected = NULL;
- c.property_received = NULL;
- b.requested = FALSE;
- b.received = FALSE;
- b.value = 0.0;
-
- /* Connect to renderer signals */
- g_signal_connect(g_gst_renderer, "error",
- G_CALLBACK(error_cb),
- &c);
- g_signal_connect(g_gst_renderer, "state-changed",
- G_CALLBACK(state_changed_cb),
- &s);
- g_signal_connect(g_gst_renderer, "buffering-info",
- G_CALLBACK(buffering_info_cb),
- &b);
-
- /* --- Get initial status --- */
-
- reset_callback_info(&c);
-
- g_debug("get status...");
- mafw_renderer_get_status(g_gst_renderer, status_cb, &s);
-
- /* --- Play object --- */
-
- reset_callback_info(&c);
-
- gchar *objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP);
- g_debug("play_object... %s", objectid);
- mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "playing an object", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object",
- "Transitioning", s.state);
- }
-
- if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) {
- fail(state_err_msg, "mafw_renderer_play_object", "Playing",
- s.state);
- }
-
- g_free(objectid);
-
- /* --- Buffering info --- */
-
- b.requested = TRUE;
-
- bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus;
- fail_if(bus == NULL, "No GstBus");
-
- message = gst_message_new_buffering(NULL, 50);
- gst_bus_post(bus, message);
-
- if (wait_for_buffering(&b, wait_tout_val) == FALSE) {
- fail("Expected buffering message but not received");
- }
-
- fail_if(b.value != 0.5, "Expected buffering 0.50 and received %1.2f",
- b.value);
-
- b.requested = FALSE;
- b.received = FALSE;
- b.value = 0;
-
- /* --- Buffering info --- */
-
- b.requested = TRUE;
-
- message = gst_message_new_buffering(NULL, 100);
- gst_bus_post(bus, message);
-
- if (wait_for_buffering(&b, wait_tout_val) == FALSE) {
- fail("Expected buffering message but not received");
- }
-
- fail_if(b.value != 1.0, "Expected buffering 1.00 and received %1.2f",
- b.value);
-
- b.requested = FALSE;
- b.received = FALSE;
- b.value = 0;
-
- /* --- Stop --- */
-
- reset_callback_info(&c);
-
- g_debug("stop...");
- mafw_renderer_stop(g_gst_renderer, playback_cb, &c);
-
- if (wait_for_callback(&c, wait_tout_val)) {
- if (c.error)
- fail(callback_err_msg, "stopping", c.err_code,
- c.err_msg);
- } else {
- fail(no_callback_msg);
- }
-
- if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) {
- fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state);
- }
-}
-END_TEST
-
-/*----------------------------------------------------------------------------
- Suit creation
- ----------------------------------------------------------------------------*/
-
-SRunner * configure_tests(void)
-{
- SRunner *sr = NULL;
- Suite *s = NULL;
- const gchar *tout = g_getenv("WAIT_TIMEOUT");
-
- if (!tout)
- wait_tout_val = DEFAULT_WAIT_TOUT;
- else
- {
- wait_tout_val = (gint)strtol(tout, NULL, 0);
- if (wait_tout_val<=0)
- wait_tout_val = DEFAULT_WAIT_TOUT;
- }
-
- checkmore_wants_dbus();
- mafw_log_init(":error");
- /* Create the suite */
- s = suite_create("MafwGstRenderer");
-
- /* Create test cases */
- TCase *tc1 = tcase_create("Playback");
-
- /* Create unit tests for test case "Playback" */
- tcase_add_checked_fixture(tc1, fx_setup_dummy_gst_renderer,
- fx_teardown_dummy_gst_renderer);
-if (1) tcase_add_test(tc1, test_basic_playback);
-if (1) tcase_add_test(tc1, test_playlist_playback);
-if (1) tcase_add_test(tc1, test_repeat_mode_playback);
-if (1) tcase_add_test(tc1, test_gst_renderer_mode);
-if (1) tcase_add_test(tc1, test_update_stats);
-if (1) tcase_add_test(tc1, test_play_state);
-if (1) tcase_add_test(tc1, test_pause_state);
-if (1) tcase_add_test(tc1, test_stop_state);
-if (1) tcase_add_test(tc1, test_transitioning_state);
-if (1) tcase_add_test(tc1, test_state_class);
-if (1) tcase_add_test(tc1, test_playlist_iterator);
-if (1) tcase_add_test(tc1, test_video);
-if (1) tcase_add_test(tc1, test_media_art);
-if (1) tcase_add_test(tc1, test_properties_management);
-if (1) tcase_add_test(tc1, test_buffering);
-
- tcase_set_timeout(tc1, 0);
-
- suite_add_tcase(s, tc1);
-
- /* Create srunner object with the test suite */
- sr = srunner_create(s);
-
- return sr;
-}
-
-/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <check.h>
-
-
-/* This must be provided by the test suite implementation */
-SRunner *configure_tests(void);
-
-int main(void)
-{
- int nf = 0;
-
- /* Configure test suites to be executed */
- SRunner *sr = configure_tests();
-
- /* Run tests */
- srunner_run_all(sr, CK_ENV);
-
- /* Retrieve number of failed tests */
- nf = srunner_ntests_failed(sr);
-
- /* Free resouces */
- srunner_free(sr);
-
- /* Return global success or failure */
- return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
-
-/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <libmafw/mafw-playlist.h>
-#include "mafw-mock-playlist.h"
-
-static GList *pl_list;
-static gchar *pl_name;
-static gboolean pl_rep;
-static gboolean pl_shuffle;
-
-/* Item manipulation */
-
-static gboolean mafw_mock_playlist_insert_item(MafwPlaylist *playlist,
- guint index,
- const gchar *objectid,
- GError **error);
-
-static gboolean mafw_mock_playlist_remove_item(MafwPlaylist *playlist,
- guint index,
- GError **error);
-
-static gchar *mafw_mock_playlist_get_item(MafwPlaylist *playlist,
- guint index, GError **error);
-
-static gboolean mafw_mock_playlist_move_item(MafwPlaylist *playlist,
- guint from, guint to,
- GError **error);
-
-static guint mafw_mock_playlist_get_size(MafwPlaylist *playlist,
- GError **error);
-
-static gboolean mafw_mock_playlist_clear(MafwPlaylist *playlist,
- GError **error);
-
-static gboolean mafw_mock_playlist_increment_use_count(MafwPlaylist *playlist,
- GError **error);
-
-static gboolean mafw_mock_playlist_decrement_use_count(MafwPlaylist *playlist,
- GError **error);
-gboolean mafw_mock_playlist_get_prev(MafwPlaylist *playlist, guint *index,
- gchar **object_id, GError **error);
-gboolean mafw_mock_playlist_get_next(MafwPlaylist *playlist, guint *index,
- gchar **object_id, GError **error);
-static void mafw_mock_playlist_get_starting_index(MafwPlaylist *playlist, guint *index,
- gchar **object_id, GError **error);
-static void mafw_mock_playlist_get_last_index(MafwPlaylist *playlist,
- guint *index, gchar **object_id,
- GError **error);
-
-enum {
- PROP_0,
- PROP_NAME,
- PROP_REPEAT,
- PROP_IS_SHUFFLED,
-};
-
-static void set_prop(MafwMockPlaylist *playlist, guint prop,
- const GValue *value, GParamSpec *spec)
-{
- if (prop == PROP_NAME) {
- pl_name = g_value_dup_string(value);
- } else if (prop == PROP_REPEAT) {
- pl_rep = g_value_get_boolean(value);
- } else
- G_OBJECT_WARN_INVALID_PROPERTY_ID(playlist, prop, spec);
-}
-
-static void get_prop(MafwMockPlaylist *playlist, guint prop,
- GValue *value, GParamSpec *spec)
-{
- if (prop == PROP_NAME) {
- g_value_take_string(value, pl_name);
- } else if (prop == PROP_REPEAT) {
- g_value_set_boolean(value, pl_rep);
- } else if (prop == PROP_IS_SHUFFLED) {
- g_value_set_boolean(value, pl_shuffle);
- } else
- G_OBJECT_WARN_INVALID_PROPERTY_ID(playlist, prop, spec);
-}
-
-static void mafw_mock_playlist_get_starting_index(MafwPlaylist *playlist, guint *index,
- gchar **object_id, GError **error)
-{
- if (g_list_length(pl_list) > 0) {
- *index = 0;
- *object_id = g_strdup(g_list_nth_data(pl_list, 0));
- }
-}
-
-static void mafw_mock_playlist_get_last_index(MafwPlaylist *playlist,
- guint *index, gchar **object_id,
- GError **error)
-{
- *index = g_list_length(pl_list) - 1;
- *object_id = g_strdup(g_list_nth_data(pl_list, *index));
-}
-
-
-gboolean mafw_mock_playlist_get_next(MafwPlaylist *playlist, guint *index,
- gchar **object_id, GError **error)
-{
- gint size;
- gboolean return_value = TRUE;
-
- size = g_list_length(pl_list);
-
- g_return_val_if_fail(size != 0, FALSE);
-
- if (*index == (size - 1)) {
- return_value = FALSE;
- } else {
- *object_id = g_strdup(g_list_nth_data(pl_list, ++(*index)));
- }
-
- return return_value;
-}
-
-gboolean mafw_mock_playlist_get_prev(MafwPlaylist *playlist, guint *index,
- gchar **object_id, GError **error)
-{
- gint size;
- gboolean return_value = TRUE;
-
- size = g_list_length(pl_list);
-
- g_return_val_if_fail(size != 0, FALSE);
-
- if (*index == 0) {
- return_value = FALSE;
- } else {
- *object_id = g_strdup(g_list_nth_data(pl_list, --(*index)));
- }
-
- return return_value;
-}
-
-static void playlist_iface_init(MafwPlaylistIface *iface)
-{
- iface->get_item = mafw_mock_playlist_get_item;
- iface->insert_item = mafw_mock_playlist_insert_item;
- iface->clear = mafw_mock_playlist_clear;
- iface->get_size = mafw_mock_playlist_get_size;
- iface->remove_item = mafw_mock_playlist_remove_item;
- iface->move_item = mafw_mock_playlist_move_item;
- iface->get_starting_index = mafw_mock_playlist_get_starting_index;
- iface->get_last_index = mafw_mock_playlist_get_last_index;
- iface->get_next = mafw_mock_playlist_get_next;
- iface->get_prev = mafw_mock_playlist_get_prev;
- iface->increment_use_count = mafw_mock_playlist_increment_use_count;
- iface->decrement_use_count = mafw_mock_playlist_decrement_use_count;
-}
-
-
-static void mafw_mock_playlist_finalize(GObject *object)
-{
- g_debug(__FUNCTION__);
-
- while (pl_list)
- {
- g_free(pl_list->data);
- pl_list = g_list_delete_link(pl_list, pl_list);
- }
-
-}
-
-static void mafw_mock_playlist_class_init(
- MafwMockPlaylistClass *klass)
-{
- GObjectClass *oclass = NULL;
-
- oclass = G_OBJECT_CLASS(klass);
-
- oclass->set_property = (gpointer)set_prop;
- oclass->get_property = (gpointer)get_prop;
- g_object_class_override_property(oclass, PROP_NAME, "name");
- g_object_class_override_property(oclass, PROP_REPEAT, "repeat");
- g_object_class_override_property(oclass,
- PROP_IS_SHUFFLED, "is-shuffled");
-
- oclass -> finalize = mafw_mock_playlist_finalize;
-}
-
-static void mafw_mock_playlist_init(MafwMockPlaylist *self)
-{
-}
-
-
-
-G_DEFINE_TYPE_WITH_CODE(MafwMockPlaylist, mafw_mock_playlist,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE(MAFW_TYPE_PLAYLIST,
- playlist_iface_init));
-
-
-GObject *mafw_mock_playlist_new(void)
-{
- MafwMockPlaylist *self;
-
- self = g_object_new(MAFW_TYPE_MOCK_PLAYLIST, NULL);
-
- return G_OBJECT(self);
-}
-
-gboolean mafw_mock_playlist_insert_item(MafwPlaylist *self, guint index,
- const gchar *objectid,
- GError **error)
-{
- pl_list = g_list_insert(pl_list, g_strdup(objectid), index);
-
- g_signal_emit_by_name(self, "contents-changed", index, 0, 1);
-
- return TRUE;
-}
-
-gboolean mafw_mock_playlist_remove_item(MafwPlaylist *self, guint index,
- GError **error)
-{
- GList *element;
-
- g_return_val_if_fail(g_list_length(pl_list) > 0, FALSE);
-
- element = g_list_nth(pl_list, index);
- g_free(element->data);
- pl_list = g_list_delete_link(pl_list, element);
-
- g_signal_emit_by_name(self, "contents-changed", index, 1, 0);
-
- return TRUE;
-}
-
-gchar *mafw_mock_playlist_get_item(MafwPlaylist *self, guint index,
- GError **error)
-{
- gchar *oid = g_list_nth_data(pl_list, index);
-
- if (oid)
- oid = g_strdup(oid);
-
- return oid;
-}
-
-guint mafw_mock_playlist_get_size(MafwPlaylist *self, GError **error)
-{
- return g_list_length(pl_list);
-}
-
-static gboolean mafw_mock_playlist_move_item(MafwPlaylist *playlist,
- guint from, guint to,
- GError **error)
-{
- GList *element_from, *element_to;
- gpointer data;
- gint size;
-
- size = g_list_length(pl_list);
-
- g_return_val_if_fail(size > 0, FALSE);
- g_return_val_if_fail(from != to, FALSE);
- g_return_val_if_fail((from < size) && (to < size), FALSE);
-
- element_from = g_list_nth(pl_list, from);
- element_to = g_list_nth(pl_list, to);
-
- data = element_from->data;
- element_from->data = element_to->data;
- element_to->data = data;
-
- g_signal_emit_by_name(playlist, "item-moved", from, to);
-
- return TRUE;
-}
-
-static gboolean mafw_mock_playlist_increment_use_count(MafwPlaylist *playlist,
- GError **error)
-{
- return TRUE;
-}
-
-static gboolean mafw_mock_playlist_decrement_use_count(MafwPlaylist *playlist,
- GError **error)
-{
- return TRUE;
-}
-
-gboolean mafw_mock_playlist_clear(MafwPlaylist *self, GError **error)
-{
- mafw_mock_playlist_finalize(NULL);
-
- return TRUE;
-}
-
-/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef MAFW_MOCK_PLAYLIST_H
-#define MAFW_MOCK_PLAYLIST_H
-
-#include <glib-object.h>
-#include <libmafw/mafw-playlist.h>
-#include <libmafw/mafw-errors.h>
-
-/*----------------------------------------------------------------------------
- GObject type conversion macros
- ----------------------------------------------------------------------------*/
-
-#define MAFW_TYPE_MOCK_PLAYLIST \
- (mafw_mock_playlist_get_type())
-
-#define MAFW_MOCK_PLAYLIST(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST(obj, MAFW_TYPE_MOCK_PLAYLIST, \
- MafwMockPlaylist))
-
-#define MAFW_MOCK_PLAYLIST_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST(klass, MAFW_TYPE_MOCK_PLAYLIST, \
- MafwMockPlaylistClass))
-
-#define MAFW_IS_MOCK_PLAYLIST(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE(obj, MAFW_TYPE_MOCK_PLAYLIST))
-
-#define MAFW_IS_MOCK_PLAYLIST_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), MAFW_TYPE_MOCK_PLAYLIST))
-
-#define MAFW_MOCK_PLAYLIST_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), MAFW_TYPE_MOCK_PLAYLIST, \
- MafwMockPlaylistClass))
-
-/*----------------------------------------------------------------------------
- GObject type definitions
- ----------------------------------------------------------------------------*/
-
-typedef struct _MafwMockPlaylist MafwMockPlaylist;
-typedef struct _MafwMockPlaylistClass MafwMockPlaylistClass;
-
-
-struct _MafwMockPlaylist
-{
- GObject parent_instance;
-
-};
-
-struct _MafwMockPlaylistClass
-{
- GObjectClass parent_class;
-
-};
-
-/*----------------------------------------------------------------------------
- Shared playlist-specific functions
- ----------------------------------------------------------------------------*/
-
-GType mafw_mock_playlist_get_type(void);
-GObject *mafw_mock_playlist_new(void);
-
-#endif
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <glib.h>
-#include "mafw-mock-pulseaudio.h"
-
-typedef void pa_glib_mainloop;
-typedef void pa_mainloop_api;
-typedef void (*pa_context_notify_cb_t)(pa_context *c, void *userdata);
-typedef guint pa_context_flags_t;
-typedef void pa_spawn_api;
-typedef void pa_operation;
-typedef guint32 pa_volume_t;
-typedef struct {
- guint8 channels;
- guint map[32];
-} pa_channel_map;
-typedef struct {
- guint8 channels;
- pa_volume_t values[32];
-} pa_cvolume;
-typedef struct {
- const gchar *name;
- pa_channel_map channel_map;
- pa_cvolume volume;
- const char *device;
- gint mute;
- gboolean volume_is_absolute;
-} pa_ext_stream_restore_info;
-typedef void (*pa_ext_stream_restore_read_cb_t)(
- pa_context *c,
- const pa_ext_stream_restore_info *info, int eol, void *userdata);
-typedef void (*pa_ext_stream_restore_subscribe_cb_t)(pa_context *c,
- void *userdata);
-typedef void (*pa_context_success_cb_t)(pa_context *c, int success,
- void *userdata);
-enum pa_context_state {
- PA_CONTEXT_UNCONNECTED = 0,
- PA_CONTEXT_CONNECTING,
- PA_CONTEXT_AUTHORIZING,
- PA_CONTEXT_SETTING_NAME,
- PA_CONTEXT_READY,
- PA_CONTEXT_FAILED,
- PA_CONTEXT_TERMINATED
-};
-struct _pa_context {
- pa_context_notify_cb_t state_cb;
- gpointer state_cb_userdata;
- enum pa_context_state state;
- pa_ext_stream_restore_read_cb_t read_cb;
- gpointer read_cb_userdata;
- pa_ext_stream_restore_subscribe_cb_t subscribe_cb;
- gpointer subscribe_cb_userdata;
- pa_cvolume volume;
- gboolean mute;
-};
-
-static pa_context *context = NULL;
-
-pa_glib_mainloop *pa_glib_mainloop_new(GMainContext *c);
-char *pa_get_binary_name(char *s, size_t l);
-pa_mainloop_api *pa_glib_mainloop_get_api(pa_glib_mainloop *g);
-pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name);
-void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb,
- void *userdata);
-int pa_context_connect(pa_context *c, const char *server,
- pa_context_flags_t flags, const pa_spawn_api *api);
-gint pa_context_get_state(pa_context *c);
-pa_operation *pa_ext_stream_restore2_read(pa_context *c,
- pa_ext_stream_restore_read_cb_t cb,
- void *userdata);
-void pa_operation_unref(pa_operation *o);
-pa_volume_t pa_cvolume_max(const pa_cvolume *volume);
-void pa_ext_stream_restore_set_subscribe_cb(
- pa_context *c,
- pa_ext_stream_restore_subscribe_cb_t cb, void *userdata);
-gint pa_operation_get_state(pa_operation *o);
-void pa_operation_cancel(pa_operation *o);
-void pa_glib_mainloop_free(pa_glib_mainloop *g);
-pa_cvolume *pa_cvolume_init(pa_cvolume *a);
-pa_cvolume *pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v);
-pa_operation *pa_ext_stream_restore2_write(
- pa_context *c, gint mode, const pa_ext_stream_restore_info *data[],
- unsigned n, int apply_immediately, pa_context_success_cb_t cb,
- void *userdata);
-pa_operation *pa_ext_stream_restore_subscribe(pa_context *c, int enable,
- pa_context_success_cb_t cb,
- void *userdata);
-void pa_context_unref(pa_context *c);
-
-pa_glib_mainloop *pa_glib_mainloop_new(GMainContext *c)
-{
- return (gpointer) 0x1;
-}
-
-char *pa_get_binary_name(char *s, size_t l)
-{
- g_strlcpy(s, "mafw-gst-renderer-tests", l);
-
- return NULL;
-}
-
-pa_mainloop_api *pa_glib_mainloop_get_api(pa_glib_mainloop *g)
-{
- return (gpointer) 0x1;
-}
-
-pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name)
-{
- pa_context *c = g_new0(pa_context, 1);
-
- pa_cvolume_set(&c->volume, 1, 32000);
-
- context = c;
-
- return c;
-}
-
-void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb,
- void *userdata)
-{
- c->state_cb = cb;
- c->state_cb_userdata = userdata;
-}
-
-static gboolean _pa_context_connect_idle(gpointer userdata)
-{
- pa_context *c = userdata;
- c->state++;
- if (c->state_cb != NULL) {
- c->state_cb(c, c->state_cb_userdata);
- }
- return c->state != PA_CONTEXT_READY;
-}
-
-int pa_context_connect(pa_context *c, const char *server,
- pa_context_flags_t flags, const pa_spawn_api *api)
-{
- g_idle_add(_pa_context_connect_idle, c);
- return 1;
-}
-
-gint pa_context_get_state(pa_context *c)
-{
- return c->state;
-}
-
-static gboolean _pa_ext_stream_restore2_read_idle(gpointer userdata)
-{
- pa_context *c = userdata;
- pa_ext_stream_restore_info info = { 0, };
-
- info.name = "sink-input-by-media-role:x-maemo";
- pa_cvolume_set(&info.volume, 1, c->volume.values[0]);
- info.mute = c->mute;
-
- c->read_cb(c, &info, 1, c->read_cb_userdata);
-
- return FALSE;
-}
-
-pa_operation *pa_ext_stream_restore2_read(pa_context *c,
- pa_ext_stream_restore_read_cb_t cb,
- void *userdata)
-{
- c->read_cb = cb;
- c->read_cb_userdata = userdata;
- g_idle_add(_pa_ext_stream_restore2_read_idle, c);
- return (gpointer) 0x1;
-}
-
-void pa_operation_unref(pa_operation *o)
-{
-}
-
-pa_volume_t pa_cvolume_max(const pa_cvolume *volume)
-{
- return volume->values[0];
-}
-
-pa_operation *pa_ext_stream_restore_subscribe(pa_context *c, int enable,
- pa_context_success_cb_t cb,
- void *userdata)
-{
- if (cb != NULL) {
- cb(c, TRUE, userdata);
- }
- return (gpointer) 0x1;
-}
-
-void pa_ext_stream_restore_set_subscribe_cb(
- pa_context *c,
- pa_ext_stream_restore_subscribe_cb_t cb, void *userdata)
-{
- c->subscribe_cb = cb;
- c->subscribe_cb_userdata = userdata;
-}
-
-gint pa_operation_get_state(pa_operation *o)
-{
- return 1;
-}
-
-void pa_operation_cancel(pa_operation *o)
-{
-}
-
-void pa_context_unref(pa_context *c)
-{
- g_free(c);
-}
-
-void pa_glib_mainloop_free(pa_glib_mainloop *g)
-{
-}
-
-pa_cvolume *pa_cvolume_init(pa_cvolume *a)
-{
- pa_cvolume_set(a, 1, 0);
- return a;
-}
-
-pa_cvolume *pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v)
-{
- a->channels = 1;
- a->values[0] = v;
- return a;
-}
-
-static gboolean _pa_ext_stream_restore_write_idle(gpointer userdata)
-{
- pa_context *c = userdata;
-
- if (c->subscribe_cb != NULL) {
- c->subscribe_cb(c, c->subscribe_cb_userdata);
- }
-
- return FALSE;
-}
-
-pa_operation *pa_ext_stream_restore2_write(
- pa_context *c, gint mode, const pa_ext_stream_restore_info *data[],
- unsigned n, int apply_immediately, pa_context_success_cb_t cb,
- void *userdata)
-{
- const pa_ext_stream_restore_info *info = data[0];
-
- pa_cvolume_set(&c->volume, 1, info->volume.values[0]);
- c->mute = info->mute;
-
- g_idle_add(_pa_ext_stream_restore_write_idle, c);
-
- return (gpointer) 0x1;
-}
-
-static gboolean _pa_context_disconnect_idle(gpointer userdata)
-{
- pa_context *c = userdata;
- c->state = PA_CONTEXT_TERMINATED;
- if (c->state_cb != NULL) {
- c->state_cb(c, c->state_cb_userdata);
- }
- return FALSE;
-}
-
-void pa_context_disconnect(pa_context *c)
-{
- g_idle_add(_pa_context_disconnect_idle, c);
-}
-
-pa_context *pa_context_get_instance(void)
-{
- return context;
-}
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef MAFW_MOCK_PULSEAUDIO_H
-#define MAFW_MOCK_PULSEAUDIO_H
-
-typedef struct _pa_context pa_context;
-
-void pa_context_disconnect(pa_context *c);
-pa_context *pa_context_get_instance(void);
-
-#endif
+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * test.c
- *
- * Test of the playback system
- *
- * Copyright (C) 2007 Nokia Corporation
- *
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <termios.h>
-
-#include "mafw-gst-renderer.h"
-#include <libmafw/mafw-metadata.h>
-#include <libmafw/mafw-registry.h>
-
-MafwGstRenderer *gst_renderer;
-GMainLoop *loop;
-static struct termios tio_orig;
-guint seek_delta = 2;
-gfloat volume = 0.7;
-gboolean muted = FALSE;
-
-
-/**
- *@time: how long to wait, in microsecs
- *
- */
-int kbhit (int time) {
- fd_set rfds;
- struct timeval tv;
- int retval;
- char c;
-
- FD_ZERO (&rfds);
- FD_SET (0, &rfds);
-
- /* Wait up to 'time' microseconds. */
- tv.tv_sec=time / 1000;
- tv.tv_usec = (time % 1000)*1000;
-
- retval=select (1, &rfds, NULL, NULL, &tv);
- if(retval < 1) return -1;
- retval = read (0, &c, 1);
- if (retval < 1) return -1;
- return (int) c;
-}
-
-
-/**
- *
- *
- */
-static void raw_kb_enable (void) {
- struct termios tio_new;
- tcgetattr(0, &tio_orig);
-
- tio_new = tio_orig;
- tio_new.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
- tio_new.c_cc[VMIN] = 1;
- tio_new.c_cc[VTIME] = 0;
- tcsetattr (0, TCSANOW, &tio_new);
-}
-
-static void raw_kb_disable (void)
-{
- tcsetattr (0,TCSANOW, &tio_orig);
-}
-
-static void get_position_cb(MafwRenderer* self, gint position, gpointer user_data,
- const GError* error)
-{
- guint* rpos = (guint*) user_data;
- g_return_if_fail(rpos != NULL);
-
- *rpos = position;
-}
-
-/**
- *
- *
- */
-static gboolean idle_cb (gpointer data)
-{
- gboolean ret = TRUE;
- GError *error = NULL;
-
- int c = kbhit (0);
- if (c == -1) {
- usleep (10 * 1000);
- return TRUE;
- }
-
- printf ("c = %d\n", c);
- /* '.' key */
- if (c == 46) {
- printf ("Seeking %d seconds forward\n", seek_delta);
- gint pos = 0;
-
- mafw_gst_renderer_get_position(MAFW_RENDERER(gst_renderer),
- get_position_cb, &pos);
-
- printf (" Position before seek: %d\n", pos);
- pos += seek_delta;
- mafw_gst_renderer_set_position(MAFW_RENDERER(gst_renderer), pos,
- NULL, NULL);
-
- mafw_gst_renderer_get_position(MAFW_RENDERER(gst_renderer),
- get_position_cb, &pos);
-
- printf (" Position after seek: %d\n", pos);
- }
- /* ',' key */
- else if (c == 44) {
- printf ("Seeking %d seconds backwards\n", seek_delta);
- gint pos = 0;
-
- mafw_gst_renderer_get_position(MAFW_RENDERER(gst_renderer),
- get_position_cb, &pos);
-
- printf (" Position before seek: %d\n", pos);
- pos -= seek_delta;
- mafw_gst_renderer_set_position(MAFW_RENDERER(gst_renderer), pos,
- NULL, NULL);
-
- mafw_gst_renderer_get_position(MAFW_RENDERER(gst_renderer),
- get_position_cb, &pos);
-
- printf (" Position after seek: %d\n", pos);
- }
- /* '' (space) key */
- else if (c == 32) {
- if (gst_renderer->current_state == Playing) {
- printf ("Pausing...\n");
- mafw_gst_renderer_pause(MAFW_RENDERER (gst_renderer), NULL, NULL);
- }
- else if (gst_renderer->current_state == Paused) {
- printf ("Resuming...\n");
- mafw_gst_renderer_resume(MAFW_RENDERER (gst_renderer), NULL, NULL);
- }
- }
- /* 'p' key */
- else if (c == 112) {
- printf ("Playing...\n");
- mafw_gst_renderer_play (MAFW_RENDERER (gst_renderer), NULL, NULL);
- }
- /* 's' key */
- else if (c == 115) {
- printf ("Stopping\n");
- mafw_gst_renderer_stop (MAFW_RENDERER (gst_renderer), NULL, NULL);
- }
- /* 'g' key */
- else if (c == 103) {
- printf ("Getting position\n");
- gint pos = 0;
-
- mafw_gst_renderer_get_position(MAFW_RENDERER(gst_renderer),
- get_position_cb, &pos);
-
- printf ("Current position: %d\n", pos);
- }
- /* '+' key */
- else if (c == 43) {
- volume += 0.1;
- printf ("Increasing volume to %lf\n", volume);
- mafw_extension_set_property_float(MAFW_EXTENSION(gst_renderer),
- "volume", volume);
- }
- /* '-' key */
- else if (c == 45) {
- volume -= 0.1;
- printf ("Decreasing volume to %lf\n", volume);
- mafw_extension_set_property_float(MAFW_EXTENSION(gst_renderer),
- "volume", volume);
- }
- /* 'm' key */
- else if (c == 109) {
- muted = !muted;
- printf ("(Un)Muting...\n");
- mafw_extension_set_property_boolean(MAFW_EXTENSION(gst_renderer),
- "mute", muted);
- }
- /* '?' key */
- else if (c == 63) {
- printf ("COMMANDS:\n" \
- " s\t\tStop\n" \
- " p\t\tPlay\n" \
- " space\tPause/Resume\n" \
- " +\t\tVolume up\n" \
- " -\t\tVolume down\n" \
- " m\t\tMute/Unmute\n" \
- " .\t\tSeek forward 2 sec\n" \
- " ,\t\tSeek backwards 2 sec\n" \
- " q\t\tQuit\n");
- }
- /* 'q' key */
- else if (c == 113) {
- printf ("QUIT\n");
- mafw_gst_renderer_stop (MAFW_RENDERER (gst_renderer), NULL, NULL);
- raw_kb_disable ();
- g_main_loop_quit (loop);
- ret = FALSE;
- }
- if (error) {
- printf ("Error occured during the operation\n");
- g_error_free (error);
- }
- return ret;
-}
-
-
-/**
- *
- *
- */
-static void metadata_changed (MafwGstRenderer *gst_renderer,
- GHashTable *metadata,
- gpointer user_data)
-{
- g_print("Metadata changed:\n");
- mafw_metadata_print (metadata, NULL);
-}
-
-
-/**
- *
- *
- */
-static void buffering_cb (MafwGstRenderer *gst_renderer,
- gfloat percentage,
- gpointer user_data)
-{
- g_print("Buffering: %f\n", percentage);
-}
-
-static void play_uri_cb(MafwRenderer* renderer, gpointer user_data, const GError* error)
-{
- if (error != NULL) {
- printf("Unable to play: %s\n", error->message);
- exit(1);
- }
-}
-
-/**
- *
- *
- */
-gint main(gint argc, gchar ** argv)
-{
- MafwRegistry *registry;
-
- g_type_init();
- gst_init (&argc, &argv);
-
- if (argc != 2) {
- g_print("Usage: mafw-test-player <media-uri>\n");
- exit(1);
- }
-
- raw_kb_enable();
-
- registry = MAFW_REGISTRY(mafw_registry_get_instance());
- gst_renderer = MAFW_GST_RENDERER(mafw_gst_renderer_new(registry));
- g_signal_connect (G_OBJECT (gst_renderer),
- "metadata_changed",
- G_CALLBACK (metadata_changed),
- gst_renderer);
-
- g_signal_connect (G_OBJECT (gst_renderer),
- "buffering_info",
- G_CALLBACK (buffering_cb),
- gst_renderer);
-
- mafw_renderer_play_uri(MAFW_RENDERER (gst_renderer), argv[1], play_uri_cb,
- NULL);
-
- loop = mafw_gst_renderer_get_loop(gst_renderer);
-
- g_idle_add (idle_cb, NULL);
- g_main_loop_run (loop);
-
- g_object_unref (G_OBJECT (gst_renderer));
- return 0;
-}
+++ /dev/null
-{
- <1>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc
- fun:g_slice_alloc
- fun:g_slice_alloc0
- fun:g_type_create_instance
- fun:g_object_constructor
- fun:g_object_newv
- fun:g_object_new_valist
- fun:g_object_new
- fun:gst_element_factory_create
- fun:gst_element_make_from_uri
- obj:*
- obj:*
- obj:*
- fun:gst_element_change_state
- fun:gst_element_continue_state
- fun:gst_element_change_state
- obj:*
- fun:gst_element_set_state
- fun:_construct_pipeline
-}
-{
- <2>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc
- fun:g_slice_alloc
- fun:g_slice_alloc0
- fun:g_type_create_instance
- fun:g_object_constructor
- fun:g_object_newv
- fun:g_object_new_valist
- fun:g_object_new
- fun:gst_pad_new_from_template
- obj:*
- fun:g_type_create_instance
- fun:g_object_constructor
- fun:g_object_newv
- fun:g_object_new_valist
- fun:g_object_new
- fun:gst_element_factory_create
- fun:gst_element_make_from_uri
- obj:*
- obj:*
-}
-{
- <3>
- Memcheck:Cond
- fun:_dl_relocate_object
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:do_dlopen
- fun:_dl_catch_error
- fun:dlerror_run
- fun:__libc_dlopen_mode
- fun:__nss_lookup_function
- fun:__nss_lookup
- fun:__nss_passwd_lookup
- fun:getpwnam_r@@GLIBC_2.1.2
-}
-{
- <4>
- Memcheck:Leak
- fun:realloc
- fun:g_realloc
- obj:*
- fun:g_signal_newv
- fun:g_signal_new_valist
- fun:g_signal_new
- obj:*
- fun:g_type_class_ref
- fun:g_type_class_ref
- fun:g_object_newv
- fun:g_object_new_valist
- fun:g_object_new
-}
-
-{
- <5>
- Memcheck:Leak
- fun:calloc
- fun:g_malloc0
- obj:*
- fun:g_type_create_instance
- obj:*
- fun:g_object_newv
- fun:g_object_new_valist
- fun:g_object_new
- fun:gst_element_factory_create
- fun:gst_element_make_from_uri
- obj:*
- obj:*
-}
-
-{
- <6>
- Memcheck:Leak
- fun:vasprintf
- fun:g_vasprintf
- fun:g_strdup_vprintf
- fun:g_strdup_printf
- fun:gst_uri_construct
- fun:g_object_newv
- obj:*
- obj:*
- fun:gst_uri_handler_set_uri
- fun:gst_element_make_from_uri
- obj:*
- obj:*
-}
-{
- <7>
- Memcheck:Leak
- fun:malloc
- fun:open_path
- fun:_dl_map_object
- fun:openaux
- fun:_dl_catch_error
- fun:_dl_map_object_deps
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
-}
-{
- <8>
- Memcheck:Leak
- fun:malloc
- fun:expand_dynamic_string_token
- fun:_dl_map_object
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
- fun:dlopen@@GLIBC_2.1
- fun:g_module_open
- fun:gst_plugin_load_file
-}
-{
- <9>
- Memcheck:Leak
- fun:malloc
- fun:_dl_new_object
- fun:_dl_map_object
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
- fun:dlopen@@GLIBC_2.1
- fun:g_module_open
-}
-{
- <10>
- Memcheck:Leak
- fun:malloc
- fun:_dl_map_object_deps
- fun:_dl_map_object
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
- fun:dlopen@@GLIBC_2.1
- fun:g_module_open
- fun:gst_plugin_load_file
- fun:gst_plugin_load_by_name
-}
-{
- <11>
- Memcheck:Leak
- fun:calloc
- fun:_dl_check_map_versions
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
- fun:dlopen@@GLIBC_2.1
- fun:g_module_open
- fun:gst_plugin_load_file
- fun:gst_plugin_load_by_name
-}
-{
- <12>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc0
- obj:*
- obj:*
- fun:g_type_create_instance
- obj:*
- fun:g_object_newv
- fun:g_object_new_valist
- fun:g_object_new
- fun:gst_element_factory_create
- fun:gst_element_make_from_uri
- obj:*
- obj:*
-}
-{
- <13>
- Memcheck:Leak
- fun:malloc
- fun:realloc
- fun:g_realloc
- obj:*
- fun:g_array_sized_new
- obj:*
- fun:gst_structure_copy
- fun:gst_caps_copy
- fun:gst_audio_filter_class_add_pad_templates
- obj:*
- fun:g_type_class_ref
- fun:gst_element_register
-}
-{
- <14>
- Memcheck:Cond
- fun:strlen
- fun:_dl_init_paths
- fun:dl_main
- fun:_dl_sysdep_start
- fun:_dl_start
-}
-{
- <15>
- Memcheck:Cond
- fun:_dl_relocate_object
- fun:dl_main
- fun:_dl_sysdep_start
- fun:_dl_start
-}
-{
- <15>
- Memcheck:Leak
- fun:calloc
- fun:allocate_dtv
- fun:_dl_allocate_tls
- fun:pthread_create@@GLIBC_2.1
- obj:*
- fun:g_thread_create_full
- obj:*
- fun:g_thread_pool_push
- fun:gst_task_start
- fun:gst_pad_start_task
- obj:*
- fun:gst_pad_activate_pull
-}
-{
- <16>
- Memcheck:Cond
- fun:_dl_relocate_object
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
- fun:dlopen@@GLIBC_2.1
- fun:g_module_open
- fun:gst_plugin_load_file
- fun:gst_plugin_load_by_name
- fun:gst_plugin_feature_load
-}
-{
- <17>
- Memcheck:Leak
- fun:malloc
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
- fun:dlopen@@GLIBC_2.1
- fun:g_module_open
- fun:gst_plugin_load_file
- fun:gst_plugin_load_by_name
- fun:gst_plugin_feature_load
-}
-{
- <17>
- Memcheck:Leak
- fun:realloc
- fun:vasprintf
- fun:g_vasprintf
- fun:g_strdup_vprintf
- fun:g_strdup_printf
- fun:gst_uri_construct
- fun:gst_file_src_set_location
- fun:gst_file_src_uri_set_uri
- fun:gst_uri_handler_set_uri
- fun:gst_element_make_from_uri
- obj:*
- obj:*
-}
-{
- <18>
- Memcheck:Leak
- fun:calloc
- fun:parse_bracket_exp
- fun:parse_expression
- fun:parse_branch
- fun:parse_reg_exp
- fun:parse_expression
- fun:parse_branch
- fun:parse_reg_exp
- fun:parse_expression
- fun:parse_branch
- fun:parse_reg_exp
- fun:re_compile_internal
-}
-{
- <19>
- Memcheck:Leak
- fun:malloc
- fun:_dl_map_object_deps
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
- fun:dlopen@@GLIBC_2.1
- fun:g_module_open
- fun:gst_plugin_load_file
- fun:gst_plugin_load_by_name
-}
-{
- <20>
- Memcheck:Leak
- fun:malloc
- fun:_dl_new_object
- fun:_dl_map_object_from_fd
- fun:_dl_map_object
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
- fun:dlopen@@GLIBC_2.1
- fun:g_module_open
-}
-{
- <21>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc
- obj:*
- obj:*
- fun:g_type_create_instance
- obj:*
- fun:g_object_newv
- fun:g_object_new_valist
- fun:g_object_new
- fun:gst_element_factory_create
- fun:gst_element_make_from_uri
- obj:*
-}
-{
- <22>
- Memcheck:Leak
- fun:calloc
- fun:dbus_malloc0
- obj:*
- obj:*
- obj:*
- obj:*
- fun:dbus_parse_address
- obj:*
- fun:dbus_connection_open
- obj:*
- fun:dbus_bus_get
- obj:*
-}
-{
- <23>
- Memcheck:Leak
- fun:realloc
- fun:g_realloc
- obj:*
- fun:g_array_append_vals
- obj:*
- fun:gst_structure_set_valist
- fun:gst_caps_set_simple
- fun:gst_riff_create_audio_caps
- fun:gst_riff_create_audio_template_caps
- obj:*
- fun:g_type_class_ref
- fun:gst_element_register
-}
-{
- <24>
- Memcheck:Leak
- fun:realloc
- fun:dbus_realloc
- obj:*
- obj:*
- obj:*
- obj:*
- obj:*
- obj:*
- obj:*
- obj:*
- obj:*
- obj:*
-}
-{
- <25>
- Memcheck:Leak
- fun:calloc
- fun:_dl_new_object
- fun:_dl_map_object_from_fd
- fun:_dl_map_object
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
- fun:dlopen@@GLIBC_2.1
- fun:g_module_open
-}
-{
- <26>
- Memcheck:Leak
- fun:realloc
- fun:vasprintf
- fun:g_vasprintf
- fun:g_strdup_vprintf
- fun:g_strdup_printf
- fun:gst_uri_construct
- obj:*
- obj:*
- fun:gst_uri_handler_set_uri
- fun:gst_element_make_from_uri
- obj:*
- obj:*
-}
-{
- <27>
- Memcheck:Leak
- fun:malloc
- fun:_dl_new_object
- fun:_dl_map_object_from_fd
- fun:_dl_map_object
- fun:dl_open_worker
- fun:_dl_catch_error
- fun:_dl_open
- fun:dlopen_doit
- fun:_dl_catch_error
- fun:_dlerror_run
- fun:dlopen@@GLIBC_2.1
- fun:g_module_open
-}
-{
- <28>
- Memcheck:Leak
- fun:realloc
- fun:vasprintf
- fun:g_vasprintf
- fun:g_strdup_vprintf
- fun:g_strdup_printf
- fun:gst_uri_construct
- obj:*
- obj:*
- fun:gst_uri_handler_set_uri
- fun:gst_element_make_from_uri
- obj:*
- obj:*
-}
-{
- <29>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc
- fun:g_strdup
- fun:gst_object_set_name
- fun:gst_element_factory_create
- fun:gst_element_make_from_uri
- obj:*
- obj:*
- obj:*
- fun:gst_element_change_state
- fun:gst_element_continue_state
- fun:gst_element_change_state
-}
-{
- <30>
- Memcheck:Cond
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:*
- obj:*
- obj:*
- obj:*
-}
-{
- <31>
- Memcheck:Cond
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
-}
-{
- <32>
- Memcheck:Cond
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- fun:__libc_dlopen_mode
- fun:__nss_lookup_function
- obj:/targets/*/lib/libc-2.5.so
- fun:__nss_passwd_lookup
- fun:getpwnam_r
- obj:/targets/*/usr/lib/libglib-2.0.so.0.1800.1
-}
-{
- <33>
- Memcheck:Cond
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- fun:__libc_dlopen_mode
- fun:__nss_lookup_function
- obj:/targets/*/lib/libc-2.5.so
- fun:__nss_passwd_lookup
- fun:getpwnam_r
- obj:/targets/*/usr/lib/libglib-2.0.so.0.1800.1
-}
-{
- <34>
- Memcheck:Leak
- fun:calloc
- fun:g_malloc0
- obj:/targets/*/usr/lib/libgobject-2.0.so.0.1800.1
- obj:/targets/*/usr/lib/libgobject-2.0.so.0.1800.1
- fun:g_type_init_with_debug_flags
- fun:g_type_init
- fun:fx_setup_dummy_gst_renderer
- fun:tcase_run_checked_setup
- fun:srunner_run_all
- fun:main
-}
-{
- <35>
- Memcheck:Leak
- fun:calloc
- fun:g_malloc0
- obj:/targets/*/usr/lib/libglib-2.0.so.0.1800.1
- fun:g_slice_alloc
- fun:g_slist_prepend
- fun:g_strsplit
- fun:mafw_log_init
- fun:configure_tests
- fun:main
-}
-{
- <36>
- Memcheck:Addr4
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libdl-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libdl-2.5.so
-}
-{
- <37>
- Memcheck:Leak
- fun:*
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- fun:reg*
- fun:mafw_source_create_objectid
- fun:get_sample_clip_objectid
- fun:*
- fun:srunner_run_all
- fun:main
-}
-{
- <38>
- Memcheck:Leak
- fun:*
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
-}
-{
- <39>
- Memcheck:Leak
- fun:*
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- fun:reg*
- fun:mafw_source_create_objectid
- fun:get_sample_clip_objectid
- fun:*
- fun:srunner_run_all
- fun:main
-}
-{
- <40>
- Memcheck:Leak
- fun:*
- obj:/targets/*/lib/libc-2.5.so
- fun:reg*
- fun:mafw_source_create_objectid
- fun:get_sample_clip_objectid
- fun:*
- fun:srunner_run_all
- fun:main
-}
-{
- <41>
- Memcheck:Leak
- fun:*
- fun:reg*
- fun:mafw_source_create_objectid
- fun:get_sample_clip_objectid
- fun:*
- fun:srunner_run_all
- fun:main
-}
-{
- <42>
- Memcheck:Leak
- fun:realloc
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- fun:regcomp
- fun:mafw_source_create_objectid
- fun:get_sample_clip_objectid
- fun:*
- fun:srunner_run_all
-}
-{
- <43>
- Memcheck:Cond
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- fun:__libc_dlopen_mode
- fun:__nss_lookup_function
- obj:/targets/*/lib/libc-2.5.so
- fun:__nss_passwd_lookup
- fun:getpwnam_r
-}
-{
- <44>
- Memcheck:Addr4
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- fun:__libc_dlopen_mode
- fun:__nss_lookup_function
- obj:/targets/*/lib/libc-2.5.so
-}
-{
- <45>
- Memcheck:Leak
- fun:malloc
- fun:fdopen
- fun:tmpfile
- fun:setup_pipe
- fun:srunner_run_all
- fun:main
-}
-{
- <46>
- Memcheck:Leak
- fun:realloc
- fun:erealloc
- fun:maybe_grow
- fun:list_add_end
- fun:_tcase_add_test
- fun:configure_tests
- fun:main
-}
-{
- <47>
- Memcheck:Leak
- fun:malloc
- fun:realloc
- fun:g_realloc
- obj:/targets/*/usr/lib/libgobject-2.0.so.0.1800.1
- fun:g_type_register_static
- fun:g_type_plugin_get_type
- fun:g_type_init_with_debug_flags
- fun:g_type_init
- fun:fx_setup_dummy_gst_renderer
- fun:tcase_run_checked_setup
- fun:srunner_run_all
- fun:main
-}
-{
- <48>
- Memcheck:Leak
- fun:*
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- obj:/targets/*/lib/libc-2.5.so
- fun:reg*
- fun:mafw_source_create_objectid
- fun:get_sample_clip_objectid
- fun:*
- fun:srunner_run_all
- fun:main
-}
-{
- <49>
- Memcheck:Leak
- fun:malloc
- fun:emalloc
- fun:suite_create
- fun:configure_tests
- fun:main
-}
-{
- <50>
- Memcheck:Leak
- fun:malloc
- fun:dbus_malloc
- obj:/targets/*/usr/lib/libdbus-1.so.3.4.0
- obj:/targets/*/usr/lib/libdbus-1.so.3.4.0
- fun:dbus_bus_get
- obj:/targets/*/usr/lib/libosso.so.1.3.0
- fun:osso_initialize
- fun:blanking_init
- fun:mafw_gst_renderer_worker_new
- fun:mafw_gst_renderer_init
- fun:g_type_create_instance
- obj:/targets/*/usr/lib/libgobject-2.0.so.0.1800.1
-}
-{
- <51>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc
- fun:g_strdup
- obj:/targets/*/usr/lib/libgstreamer-0.10.so.0.18.0
- fun:gst_registry_binary_read_cache
- obj:/targets/*/usr/lib/libgstreamer-0.10.so.0.18.0
- obj:/targets/*/usr/lib/libgstreamer-0.10.so.0.18.0
- fun:g_option_context_parse
- fun:gst_init_check
- fun:gst_init
- fun:mafw_gst_renderer_class_init
- fun:mafw_gst_renderer_class_intern_init
-}
-{
- <52>
- Memcheck:Leak
- fun:*
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libdl-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libdl-2.5.so
- fun:dlopen
- fun:g_module_open
-}
-{
- <53>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc
- fun:g_slice_alloc
- fun:g_hash_table_new_full
- fun:g_hash_table_new
- fun:g_quark_from_static_string
- fun:g_type_init_with_debug_flags
- fun:g_type_init
- fun:fx_setup_dummy_gst_renderer
- fun:tcase_run_checked_setup
- fun:srunner_run_all
- fun:main
-}
-{
- <54>
- Memcheck:Leak
- fun:*
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libdl-2.5.so
- obj:/targets/*/lib/ld-2.5.so
- obj:/targets/*/lib/libdl-2.5.so
-}
-{
- <55>
- Memcheck:Leak
- fun:malloc
- fun:fdopen
- fun:tmpfile
- fun:setup_pipe
- fun:receive_test_result
- fun:srunner_run_all
- fun:main
-}