Bug 485291 - Update liboggplay to b4a7efa06d46596515071490cb255c3548d90371. rs=roc, r=ted.mielczarek for build changes, r=chris.double for local liboggplay changes

--HG--
extra : rebase_source : 84b9322bc764ff70d0df4bd9ff51c3ec243bdc1d
This commit is contained in:
Matthew Gregan 2009-04-04 01:56:22 +13:00
Родитель 58756ff209
Коммит 1922412388
64 изменённых файлов: 1978 добавлений и 1807 удалений

Просмотреть файл

@ -5446,6 +5446,27 @@ if test -n "$MOZ_OGG"; then
AC_DEFINE(MOZ_OGG)
MOZ_SYDNEYAUDIO=1
MOZ_MEDIA=1
dnl Checks for __attribute__(aligned()) directive
AC_CACHE_CHECK([__attribute__ ((aligned ())) support],
[ac_cv_c_attribute_aligned],
[ac_cv_c_attribute_aligned=0
CFLAGS_save="${CFLAGS}"
CFLAGS="${CFLAGS} -Werror"
for ac_cv_c_attr_align_try in 64 32 16 8; do
echo "trying $ac_cv_c_attr_align_try"
AC_TRY_COMPILE([],
[static char c __attribute__ ((aligned(${ac_cv_c_attr_align_try}))) = 0; return c;],
[ac_cv_c_attribute_aligned="${ac_cv_c_attr_align_try}"])
if test "$ac_cv_c_attribute_aligned" != 0; then
break;
fi
done
CFLAGS="${CFLAGS_save}"])
if test "${ac_cv_c_attribute_aligned}" != "0"; then
AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX],
[${ac_cv_c_attribute_aligned}],[Maximum supported data alignment])
fi
fi
dnl ========================================================

Просмотреть файл

@ -726,11 +726,7 @@ void nsOggDecodeStateMachine::PlayVideo(FrameData* aFrame)
rgb.rgb_width = aFrame->mVideoWidth;
rgb.rgb_height = aFrame->mVideoHeight;
#ifdef IS_BIG_ENDIAN
oggplay_yuv2argb(&yuv, &rgb);
#else
oggplay_yuv2bgr(&yuv, &rgb);
#endif
oggplay_yuv2bgra(&yuv, &rgb);
mDecoder->SetRGBData(aFrame->mVideoWidth, aFrame->mVideoHeight, mFramerate, buffer.forget());
}

Просмотреть файл

@ -66,6 +66,7 @@ _TEST_FILES += \
test_bug448534.html \
test_bug461281.html \
test_bug468190.html \
test_bug482461.html \
test_can_play_type_ogg.html \
test_contentDuration1.html \
test_contentDuration2.html \
@ -94,6 +95,7 @@ _TEST_FILES += \
320x240.allow-origin.ogv \
320x240.allow-origin.ogv^headers^ \
bug461281.ogg \
bug482461.ogv \
redirect.sjs \
contentDuration1.sjs \
contentDuration2.sjs \

Двоичные данные
content/media/video/test/bug482461.ogv Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=482461
-->
<head>
<title>Media test: Bug 482461 - Play oggz-chop streams</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=482461">Mozilla Bug 482461</a>
<pre id="test">
<script class="testbody" type="text/javascript">
var v;
var endPassed = false;
var completed = false;
function startTest() {
if (completed)
return false;
v = document.getElementById('v');
v.play();
return false;
}
function playbackEnded() {
if (completed)
return false
completed = true;
ok(v.currentTime > 608 && v.currentTime < 610,
"Checking currentTime at end: " + v.currentTime);
ok(v.ended, "Checking playback has ended");
SimpleTest.finish();
return false;
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
<video id='v'
src='bug482461.ogv'
onloadedmetadata='return startTest();'
onended='return playbackEnded();'></video>
</body>
</html>

Просмотреть файл

@ -32,5 +32,14 @@
</feComponentTransfer>
</filter>
<!-- Threshold colours into sixteen steps per channel. -->
<filter id="ThresholdRGB" x="0%" y="0%" width="100%" height="100%" color-interpolation-filters="sRGB">
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0 .125 .25 .375 .5 .625 .75 .875 1" />
<feFuncG type="discrete" tableValues="0 .125 .25 .375 .5 .625 .75 .875 1" />
<feFuncB type="discrete" tableValues="0 .125 .25 .375 .5 .625 .75 .875 1" />
</feComponentTransfer>
</filter>
</defs>
</svg>

До

Ширина:  |  Высота:  |  Размер: 1.5 KiB

После

Ширина:  |  Высота:  |  Размер: 1.9 KiB

Просмотреть файл

@ -1,8 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<body style="background:white;">
<video id="v" src="black140x100.ogv"
style="width:340px; height:100px; position:relative; top:100px;"
onloadeddata="document.documentElement.removeAttribute('class')"></video>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body style="background:white;">
<video src="black140x100.ogv" style="width:340px; height:100px; position:relative; top:100px;"></video>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 598 B

Просмотреть файл

@ -1,7 +0,0 @@
<!DOCTYPE HTML>
<html>
<body style="background:white;">
<video id="v" src="black140x100.ogv"
style="width:140px; height:300px; position:relative; left:100px;"></video>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body style="background:white;">
<video src="black140x100.ogv" style="width:140px; height:300px; position:relative; left:100px;"></video>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 601 B

Просмотреть файл

@ -1,7 +0,0 @@
<!DOCTYPE HTML>
<html>
<body style="background:white;">
<video id="v" src="black140x100.ogv"
style="width:680px; height:200px; position:relative; top:200px;"></video>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body style="background:white;">
<video src="black140x100.ogv" style="width:680px; height:200px; position:relative; top:200px;"></video>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 598 B

Просмотреть файл

@ -1,7 +0,0 @@
<!DOCTYPE HTML>
<html>
<body style="background:white;">
<video id="v" src="black140x100.ogv"
style="width:280px; height:600px; position:relative; left:200px;"></video>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body style="background:white;">
<video src="black140x100.ogv" style="width:280px; height:600px; position:relative; left:200px;"></video>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 601 B

Просмотреть файл

@ -1,8 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<body style="background:white;">
<video id="v" src="black140x100.ogv"
style="width:280px; height:200px;"
onloadeddata="document.documentElement.removeAttribute('class')"></video>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body style="background:white;">
<video src="black140x100.ogv" style="width:280px; height:200px;"></video>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 568 B

Просмотреть файл

@ -1,7 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<body style="background:white;">
<video id="v" src="black140x100.ogv" width="280"
onloadeddata="document.documentElement.removeAttribute('class')"></video>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body style="background:white;">
<video src="black140x100.ogv" width="280"></video>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 547 B

Просмотреть файл

@ -1,7 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<body style="background:white;">
<video id="v" src="black140x100.ogv" height="200"
onloadeddata="document.documentElement.removeAttribute('class')"></video>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body style="background:white;">
<video src="black140x100.ogv" height="200"></video>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 546 B

Просмотреть файл

@ -1,6 +0,0 @@
<!DOCTYPE HTML>
<html>
<body style="background:white;">
<video id="v" src="black140x100.ogv"></video>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body style="background:white;">
<video src="black140x100.ogv"></video>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 533 B

Просмотреть файл

@ -1,18 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<body>
<canvas id="canvas" width="200" height="200"></canvas>
<script>
var video = document.createElement("video");
video.src = "black140x100.ogv";
video.load();
function draw() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
document.documentElement.removeAttribute("class");
}
video.addEventListener("loadeddata", draw, false);
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" class="reftest-wait">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body>
<canvas id="canvas" width="200" height="200"></canvas>
<script>
var video = document.createElement("video");
video.src = "black140x100.ogv";
video.load();
function draw() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
try {
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
} catch (e) {
}
document.documentElement.removeAttribute("class");
}
video.addEventListener("loadeddata", draw, false);
</script>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 964 B

Просмотреть файл

@ -1,16 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<body>
<canvas id="canvas" width="200" height="200"></canvas>
<script>
function draw() {
var video = document.getElementById("video");
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
document.documentElement.removeAttribute("class");
}
</script>
<video id="video" src="black140x100.ogv" onloadeddata="draw()" style="opacity:0"></video>
</body>
</html>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body>
<canvas id="canvas" width="200" height="200"></canvas>
<script>
function draw() {
var video = document.getElementById("video");
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
try {
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
} catch (e) {
}
document.documentElement.removeAttribute("class");
}
</script>
<video id="video" src="black140x100.ogv" onloadeddata="draw()" style="opacity:0"></video>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 939 B

Просмотреть файл

@ -1,6 +1,6 @@
<!DOCTYPE HTML>
<html>
<body style="background:white;">
<video id="v" src="black140x100.ogv" style="width:0"></video>
<video src="black140x100.ogv" style="width:0"></video>
</body>
</html>

Просмотреть файл

@ -1,6 +1,6 @@
<!DOCTYPE HTML>
<html>
<body style="background:white;">
<video id="v" src="black140x100.ogv" style="height:0"></video>
<video src="black140x100.ogv" style="height:0"></video>
</body>
</html>

Просмотреть файл

@ -1,12 +1,12 @@
== aspect-ratio-1a.html aspect-ratio-1-ref.html
== aspect-ratio-1b.html aspect-ratio-1-ref.html
skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") == aspect-ratio-2a.html aspect-ratio-2-ref.html
skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") == aspect-ratio-2b.html aspect-ratio-2-ref.html
== aspect-ratio-3a.html aspect-ratio-3-ref.html
== aspect-ratio-3b.html aspect-ratio-3-ref.html
== basic-1.html basic-1-ref.html
== canvas-1a.html basic-1-ref.html
== canvas-1b.html basic-1-ref.html
HTTP(..) == aspect-ratio-1a.xhtml aspect-ratio-1-ref.html
HTTP(..) == aspect-ratio-1b.xhtml aspect-ratio-1-ref.html
skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") HTTP(..) == aspect-ratio-2a.xhtml aspect-ratio-2-ref.html
skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") HTTP(..) == aspect-ratio-2b.xhtml aspect-ratio-2-ref.html
HTTP(..) == aspect-ratio-3a.xhtml aspect-ratio-3-ref.xhtml
HTTP(..) == aspect-ratio-3b.xhtml aspect-ratio-3-ref.xhtml
HTTP(..) == basic-1.xhtml basic-1-ref.html
random HTTP(..) == canvas-1a.xhtml basic-1-ref.html
random HTTP(..) == canvas-1b.xhtml basic-1-ref.html
== empty-1a.html empty-1-ref.html
== empty-1b.html empty-1-ref.html
skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") == zoomed-1.html zoomed-1-ref.html
skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") HTTP(..) == zoomed-1.xhtml zoomed-1-ref.html

Просмотреть файл

@ -1,6 +1,6 @@
<!DOCTYPE HTML>
<html>
<body style="background:white; margin:0;">
<div style="width:210px; height:150px; background:black;"></div>
<div style="width:210px; height:150px; background:#010101;"></div>
</body>
</html>

Просмотреть файл

@ -1,6 +0,0 @@
<!DOCTYPE HTML>
<html reftest-zoom="1.5">
<body style="background:white; margin:0">
<video id="v" src="black140x100.ogv"></video>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" reftest-zoom="1.5">
<!-- use an empty g to force filters.svg to load before onload -->
<use xlink:href="../filters.svg#empty" />
<foreignObject x="0" y="0" height="100%" width="100%">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body style="background:white; margin:0">
<video src="black140x100.ogv"></video>
</body>
</html>
</foreignObject>
</svg>

После

Ширина:  |  Высота:  |  Размер: 519 B

Просмотреть файл

@ -29,6 +29,15 @@ Optionally, for Kate stream support, you need
* libkate -- from http://libkate.googlecode.com/
To render Kate streams as video overlays, you need
* libtiger -- from http://libtiger.googlecode.com/
Note that libtiger needs Pango and Cairo:
* Pango -- http://www.pango.org/
* Cairo -- http://cairographics.com/
See the README files associated with these libraries for installation
instructions.

Просмотреть файл

@ -3,21 +3,12 @@ source using the update.sh script. The only changes made were those
applied by update.sh and the addition/upate of Makefile.in files for
the Mozilla build system.
http://svn.annodex.net/liboggplay/trunk/
git://git.xiph.org/liboggplay.git
The svn revision number used was r3848.
The git commit ID used was b4a7efa06d46596515071490cb255c3548d90371.
The patch from Bug 468327 (yuv_disable_optimized.patch) is applied
to disable optimized yuv to rgb routines.
The following local patches have been applied:
The patch from Bug 452698 (yuv2argb.patch) is applied to fix
yuv to rgb conversion on PPC Mac OS X.
bug485291_yuv_align: only use optimized YUV routines if video dimensions are a multiple of the
optimized routine's supported alignment.
Apply patch from bug 468281 to get liboggplay svn r3863 changeset.
The patch for this is in bug468281_r3863.patch.
Apply patch from bug 468281 to get liboggplay svn r3864 changeset.
The patch for this is in bug468281_r3864.patch.
Apply patch from bug 468281 to get liboggplay svn r3871 changeset.
The patch for this is in bug468281_r3871.patch.

Просмотреть файл

@ -1,975 +0,0 @@
diff --git a/include/oggplay/oggplay.h b/include/oggplay/oggplay.h
index 019958a..cdcb168 100644
--- a/include/oggplay/oggplay.h
+++ b/include/oggplay/oggplay.h
@@ -56,20 +56,27 @@ typedef int (OggPlayDataCallback)(OggPlay *player, int num_records,
#include <oggplay/oggplay_callback_info.h>
#include <oggplay/oggplay_tools.h>
#include <oggplay/oggplay_seek.h>
-/*
-#include <oggplay/oggplay_retrieve.h>
-#include <oggplay/oggplay_cmml.h>
-*/
-
-OggPlay *
-oggplay_init(void);
-
-OggPlayErrorCode
-oggplay_set_reader(OggPlay *OS, OggPlayReader *OSR);
+/**
+ * Create an OggPlay handle associated with the given reader.
+ * The functions creates a new OggPlay handle and associates with
+ * the given OggPlayReader and initialises the buffer.
+ *
+ *
+ * @param reader an OggPlayReader handle associated with the Ogg content
+ * @return A new OggPlay handle
+ * @retval NULL in case of error.
+ */
OggPlay *
oggplay_open_with_reader(OggPlayReader *reader);
+/**
+ * Create a new OggPlay handle associated with the given reader.
+ *
+ * \param reader OggPlayReader handle associated with the Ogg content
+ * \return A new OggPlay handle
+ * \retval NULL in case of error.
+ */
OggPlay *
oggplay_new_with_reader(OggPlayReader *reader);
@@ -128,6 +135,13 @@ oggplay_buffer_release(OggPlay *player, OggPlayCallbackInfo **track_info);
void
oggplay_prepare_for_close(OggPlay *me);
+/**
+ * @brief Destroys the OggPlay handle along with the associated OggPlayReader
+ * and clears out the buffer and shuts down the callback function.
+ *
+ * @param player an OggPlay handle
+ * @retval E_OGGPLAY_OK on success
+ */
OggPlayErrorCode
oggplay_close(OggPlay *player);
diff --git a/include/oggplay/oggplay_enums.h b/include/oggplay/oggplay_enums.h
index cda068f..6f4790f 100644
--- a/include/oggplay/oggplay_enums.h
+++ b/include/oggplay/oggplay_enums.h
@@ -62,6 +62,7 @@ typedef enum OggPlayErrorCode {
E_OGGPLAY_TIMEOUT = -17,
E_OGGPLAY_CANT_SEEK = -18,
E_OGGPLAY_NO_KATE_SUPPORT = -19,
+ E_OGGPLAY_OUT_OF_MEMORY = -20,
E_OGGPLAY_NOTCHICKENPAYBACK = -777
} OggPlayErrorCode;
diff --git a/include/oggplay/oggplay_reader.h b/include/oggplay/oggplay_reader.h
index 992f416..21b5206 100644
--- a/include/oggplay/oggplay_reader.h
+++ b/include/oggplay/oggplay_reader.h
@@ -63,9 +63,25 @@ typedef struct _OggPlayReader {
long (*io_tell)(void *user_handle);
} OggPlayReader;
+/**
+ * Create and initialise an OggPlayReader for a given Ogg file.
+ *
+ * @param filename The file to open
+ * @return A new OggPlayReader handle
+ * @retval NULL on error.
+ */
OggPlayReader *
oggplay_file_reader_new(char *filename);
+/**
+ * Create and initialise an OggPlayReader for an Ogg content at a given URI.
+ *
+ * @param uri The URI to the Ogg file.
+ * @param proxy Proxy
+ * @param proxy_port Proxy port.
+ * @return A new OggPlayReader handle
+ * @retval NULL on error.
+ */
OggPlayReader *
oggplay_tcp_reader_new(char *uri, char *proxy, int proxy_port);
diff --git a/src/liboggplay/oggplay.c b/src/liboggplay/oggplay.c
index c71d639..8fa3b9e 100644
--- a/src/liboggplay/oggplay.c
+++ b/src/liboggplay/oggplay.c
@@ -48,7 +48,15 @@
OggPlay *
oggplay_new_with_reader(OggPlayReader *reader) {
- OggPlay * me = (OggPlay *)malloc(sizeof(OggPlay));
+ OggPlay * me = NULL;
+
+ /* check whether the reader is valid. */
+ if (reader == NULL)
+ return NULL;
+
+ me = (OggPlay *)oggplay_malloc (sizeof(OggPlay));
+ if (me == NULL)
+ return NULL;
me->reader = reader;
me->decode_data = NULL;
@@ -94,10 +102,20 @@ oggplay_initialise(OggPlay *me, int block) {
* the main loop
*/
me->oggz = oggz_new(OGGZ_READ | OGGZ_AUTO);
- oggz_io_set_read(me->oggz, me->reader->io_read, me->reader);
- oggz_io_set_seek(me->oggz, me->reader->io_seek, me->reader);
- oggz_io_set_tell(me->oggz, me->reader->io_tell, me->reader);
- oggz_set_read_callback(me->oggz, -1, oggplay_callback_predetected, me);
+ if (me->oggz == NULL)
+ return E_OGGPLAY_OGGZ_UNHAPPY;
+
+ if (oggz_io_set_read(me->oggz, me->reader->io_read, me->reader) != 0)
+ return E_OGGPLAY_OGGZ_UNHAPPY;
+
+ if (oggz_io_set_seek(me->oggz, me->reader->io_seek, me->reader) != 0)
+ return E_OGGPLAY_OGGZ_UNHAPPY;
+
+ if (oggz_io_set_tell(me->oggz, me->reader->io_tell, me->reader) != 0)
+ return E_OGGPLAY_OGGZ_UNHAPPY;
+
+ if (oggz_set_read_callback(me->oggz, -1, oggplay_callback_predetected, me))
+ return E_OGGPLAY_OGGZ_UNHAPPY;
while (1) {
@@ -131,15 +149,20 @@ oggplay_initialise(OggPlay *me, int block) {
OggPlay *
oggplay_open_with_reader(OggPlayReader *reader) {
- OggPlay *me = oggplay_new_with_reader(reader);
-
+ OggPlay *me = NULL;
int r = E_OGGPLAY_TIMEOUT;
+
+ if ( (me = oggplay_new_with_reader(reader)) == NULL)
+ return NULL;
+
while (r == E_OGGPLAY_TIMEOUT) {
r = oggplay_initialise(me, 0);
}
if (r != E_OGGPLAY_OK) {
- free(me);
+ /* in case of error close the OggPlay handle */
+ oggplay_close(me);
+
return NULL;
}
@@ -195,6 +218,7 @@ oggplay_set_callback_num_frames(OggPlay *me, int track, int frames) {
me->callback_period = me->decode_data[track]->granuleperiod * frames;
me->target = me->presentation_time + me->callback_period - 1;
+// printf("targ: %lld, callback_per: %lld, prestime: %lld\n", me->target, me->callback_period,me->presentation_time );
return E_OGGPLAY_OK;
@@ -524,8 +548,10 @@ read_more_data:
/*
* ensure all tracks have their final data packet set to end_of_stream
+ * But skip doing this if we're shutting down --- me->buffer may not
+ * be in a safe state.
*/
- if (me->buffer != NULL) {
+ if (me->buffer != NULL && !me->shutdown) {
oggplay_buffer_set_last_data(me, me->buffer);
}
@@ -594,17 +620,21 @@ oggplay_close(OggPlay *me) {
me->reader->destroy(me->reader);
}
- for (i = 0; i < me->num_tracks; i++) {
- oggplay_callback_shutdown(me->decode_data[i]);
+
+ if (me->decode_data) {
+ for (i = 0; i < me->num_tracks; i++) {
+ oggplay_callback_shutdown(me->decode_data[i]);
+ }
}
- oggz_close(me->oggz);
+ if (me->oggz)
+ oggz_close(me->oggz);
if (me->buffer != NULL) {
oggplay_buffer_shutdown(me, me->buffer);
}
- free(me);
+ oggplay_free(me);
return E_OGGPLAY_OK;
}
@@ -685,3 +715,4 @@ oggplay_media_finished_retrieving(OggPlay *me) {
return me->reader->finished_retrieving(me->reader);
}
+
diff --git a/src/liboggplay/oggplay_buffer.c b/src/liboggplay/oggplay_buffer.c
index e752f33..b116c7f 100644
--- a/src/liboggplay/oggplay_buffer.c
+++ b/src/liboggplay/oggplay_buffer.c
@@ -53,26 +53,43 @@
OggPlayBuffer *
oggplay_buffer_new_buffer(int size) {
- OggPlayBuffer *buffer = 0;
+ OggPlayBuffer *buffer = NULL;
if (size < 0) {
size = OGGPLAY_DEFAULT_BUFFER_SIZE;
}
- buffer = (OggPlayBuffer*)malloc(sizeof (OggPlayBuffer));
+ buffer = (OggPlayBuffer*)oggplay_malloc(sizeof (OggPlayBuffer));
- buffer->buffer_list = malloc(sizeof (void *) * size);
- memset(buffer->buffer_list, 0, sizeof (void *) * size);
- buffer->buffer_mirror = malloc(sizeof (void *) * size);
- memset(buffer->buffer_mirror, 0, sizeof (void *) * size);
+ if (buffer == NULL)
+ return NULL;
+
+ buffer->buffer_list = oggplay_calloc(size, sizeof (void *));
+ if (buffer->buffer_list == NULL)
+ goto error;
+
+ buffer->buffer_mirror = oggplay_calloc(size, sizeof (void *));
+ if (buffer->buffer_mirror == NULL)
+ goto error;
buffer->buffer_size = size;
buffer->last_filled = -1;
buffer->last_emptied = -1;
- SEM_CREATE(buffer->frame_sem, size);
+ if (SEM_CREATE(buffer->frame_sem, size) != 0)
+ goto error;
return buffer;
+error:
+ if (buffer->buffer_list != NULL)
+ oggplay_free (buffer->buffer_list);
+
+ if (buffer->buffer_mirror != NULL)
+ oggplay_free (buffer->buffer_mirror);
+
+ oggplay_free (buffer);
+
+ return NULL;
}
void
@@ -87,16 +104,16 @@ oggplay_buffer_shutdown(OggPlay *me, volatile OggPlayBuffer *vbuffer) {
if (buffer->buffer_mirror[i] != NULL) {
OggPlayCallbackInfo *ti = (OggPlayCallbackInfo *)buffer->buffer_mirror[i];
for (j = 0; j < me->num_tracks; j++) {
- free((ti + j)->records);
+ oggplay_free((ti + j)->records);
}
- free(ti);
+ oggplay_free(ti);
}
}
- free(buffer->buffer_list);
- free(buffer->buffer_mirror);
+ oggplay_free(buffer->buffer_list);
+ oggplay_free(buffer->buffer_mirror);
SEM_CLOSE(buffer->frame_sem);
- free(buffer);
+ oggplay_free(buffer);
}
int
@@ -147,6 +164,9 @@ oggplay_buffer_callback(OggPlay *me, int tracks,
OggPlayCallbackInfo * ptr = track_info[0];
int required;
+ if (me == NULL)
+ return -1;
+
buffer = (OggPlayBuffer *)me->buffer;
if (buffer == NULL) {
@@ -190,9 +210,9 @@ oggplay_buffer_callback(OggPlay *me, int tracks,
/* free these here, because we couldn't free them in
* oggplay_callback_info_destroy for buffer mode
*/
- free((ti + i)->records);
+ oggplay_free((ti + i)->records);
}
- free(ti);
+ oggplay_free(ti);
buffer->buffer_mirror[k] = NULL;
}
}
@@ -200,7 +220,10 @@ oggplay_buffer_callback(OggPlay *me, int tracks,
/*
* replace the decode_data buffer for the next callback
*/
- me->callback_info = (OggPlayCallbackInfo *)calloc(me->num_tracks, sizeof (OggPlayCallbackInfo));
+ me->callback_info =
+ (OggPlayCallbackInfo *)oggplay_calloc(me->num_tracks, sizeof (OggPlayCallbackInfo));
+ if (me->callback_info == NULL)
+ return -1;
/*
* fill both mirror and list, mirror first to avoid getting inconsistencies
@@ -256,7 +279,9 @@ oggplay_buffer_retrieve_next(OggPlay *me) {
next_item = (OggPlayCallbackInfo*)buffer->buffer_list[next_loc];
buffer->last_emptied = next_loc;
- return_val = malloc(sizeof (OggPlayCallbackInfo *) * me->num_tracks);
+ return_val = oggplay_calloc(me->num_tracks, sizeof (OggPlayCallbackInfo *));
+ if (return_val == NULL)
+ return NULL;
for (i = 0; i < me->num_tracks; i++) {
return_val[i] = next_item + i;
@@ -289,7 +314,7 @@ oggplay_buffer_release(OggPlay *me, OggPlayCallbackInfo **track_info) {
return E_OGGPLAY_UNINITIALISED;
}
- free(track_info);
+ oggplay_free(track_info);
buffer->buffer_list[buffer->last_emptied] = NULL;
@@ -317,7 +342,8 @@ oggplay_use_buffer(OggPlay *me, int size) {
return E_OGGPLAY_OK;
}
- me->buffer = oggplay_buffer_new_buffer(size);
+ if( (me->buffer = oggplay_buffer_new_buffer(size)) == NULL)
+ return E_OGGPLAY_OUT_OF_MEMORY;
/*
* if oggplay is already initialised, then prepare the buffer now
@@ -334,6 +360,9 @@ oggplay_buffer_prepare(OggPlay *me) {
int i;
+ if (me == NULL)
+ return;
+
oggplay_set_data_callback_force(me, &oggplay_buffer_callback, NULL);
for (i = 0; i < me->num_tracks; i++) {
diff --git a/src/liboggplay/oggplay_buffer.h b/src/liboggplay/oggplay_buffer.h
index a356514..7a38976 100644
--- a/src/liboggplay/oggplay_buffer.h
+++ b/src/liboggplay/oggplay_buffer.h
@@ -39,6 +39,13 @@
#ifndef __OGGPLAY_BUFFER_H__
#define __OGGPLAY_BUFFER_H__
+/**
+ * Creates a new buffer with the given size.
+ *
+ * @param size The number of frames the buffer can store.
+ * @return A new OggPlayBuffer.
+ * @retval NULL in case of error.
+ */
OggPlayBuffer *
oggplay_buffer_new_buffer(int size);
diff --git a/src/liboggplay/oggplay_callback.c b/src/liboggplay/oggplay_callback.c
index 6916838..5a4d1ba 100644
--- a/src/liboggplay/oggplay_callback.c
+++ b/src/liboggplay/oggplay_callback.c
@@ -315,6 +315,8 @@ oggplay_fish_sound_callback_floats(FishSound * fsound, float ** pcm,
*/
oggplay_data_handle_audio_data(&(decoder->decoder), (short *)pcm, frames,
sizeof(float));
+
+ return FISH_SOUND_STOP_ERR;
}
return FISH_SOUND_CONTINUE;
@@ -473,10 +475,17 @@ OggPlayCallbackFunctions callbacks[] = {
OggPlayDecode *
oggplay_initialise_decoder(OggPlay *me, int content_type, int serialno) {
- ogg_int64_t num;
- ogg_int64_t denom;
+ ogg_int64_t num;
+ ogg_int64_t denom;
+ OggPlayDecode *decoder = NULL;
+
+ if (me == NULL)
+ return NULL;
+
+ decoder = oggplay_malloc (callbacks[content_type].size);
- OggPlayDecode * decoder = malloc (callbacks[content_type].size);
+ if (decoder == NULL)
+ return NULL;
decoder->serialno = serialno;
decoder->content_type = content_type;
@@ -538,8 +547,7 @@ oggplay_callback_shutdown(OggPlayDecode *decoder) {
oggplay_data_shutdown_list(decoder);
- free(decoder);
-
+ oggplay_free(decoder);
}
@@ -595,11 +603,20 @@ oggplay_callback_predetected (OGGZ *oggz, ogg_packet *op, long serialno,
}
}
- me->callback_info = realloc (me->callback_info,
+ me->callback_info = oggplay_realloc (me->callback_info,
sizeof (OggPlayCallbackInfo) * ++me->num_tracks);
- me->decode_data = realloc (me->decode_data, sizeof (long) * me->num_tracks);
+ if (me->callback_info == NULL)
+ return -1;
+
+ me->decode_data = oggplay_realloc (me->decode_data, sizeof (long) * me->num_tracks);
+ if (me->decode_data == NULL)
+ return -1;
+
me->decode_data[me->num_tracks - 1] = oggplay_initialise_decoder(me,
content_type, serialno);
+ if (me->decode_data[me->num_tracks - 1] == NULL)
+ return -1;
+
/*me->decode_data->callback_info = me->callback_info + (me->num_tracks - 1);*/
/*
diff --git a/src/liboggplay/oggplay_callback.h b/src/liboggplay/oggplay_callback.h
index b6e1204..c6ddac1 100644
--- a/src/liboggplay/oggplay_callback.h
+++ b/src/liboggplay/oggplay_callback.h
@@ -45,6 +45,17 @@ oggplay_callback_predetected (OGGZ *oggz, ogg_packet *op, long serialno,
void
oggplay_process_leftover_packet(OggPlay *me);
+/**
+ * Create and initialise an OggPlayDecode handle.
+ *
+ *
+ *
+ * @param me OggPlay
+ * @param content_type
+ * @param serialno
+ * @return A new OggPlayDecode handle
+ * @retval NULL in case of error.
+ */
OggPlayDecode *
oggplay_initialise_decoder(OggPlay *me, int content_type, int serialno);
diff --git a/src/liboggplay/oggplay_callback_info.c b/src/liboggplay/oggplay_callback_info.c
index 2363744..cbfb6ab 100644
--- a/src/liboggplay/oggplay_callback_info.c
+++ b/src/liboggplay/oggplay_callback_info.c
@@ -40,7 +40,7 @@
#define M(x) ((x) >> 32)
-void _print_list(char *name, OggPlayDataHeader *p);
+extern void _print_list(char *name, OggPlayDataHeader *p);
int
oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info) {
@@ -56,7 +56,9 @@ oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info) {
/*
* allocate the structure for return to the user
*/
- (*info) = malloc (me->num_tracks * sizeof (OggPlayCallbackInfo *));
+ (*info) = oggplay_calloc (me->num_tracks, sizeof (OggPlayCallbackInfo *));
+ if ((*info) == NULL)
+ return -1;
/*
* fill in each active track. Leave gaps for inactive tracks.
@@ -128,7 +130,18 @@ oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info) {
}
/* null-terminate the record list for the python interface */
- track_info->records = malloc ((count + 1) * sizeof (OggPlayDataHeader *));
+ track_info->records = oggplay_calloc ((count + 1), sizeof (OggPlayDataHeader *));
+ if (track_info->records == NULL)
+ {
+ for (i = 0; i < me->num_tracks; i++) {
+ if ((*info)[i]->records != NULL)
+ oggplay_free ((*info)[i]->records);
+ }
+ oggplay_free (*info);
+ *info = NULL;
+ return -1;
+ }
+
track_info->records[count] = NULL;
track_info->available_records = count;
@@ -270,18 +283,20 @@ oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info) {
* and callback creation
*/
for (i = 0; i < me->num_tracks; i++) {
- if ((*info)[i]->records != NULL) free((*info)[i]->records);
+ if ((*info)[i]->records != NULL)
+ oggplay_free((*info)[i]->records);
}
- free(*info);
+ oggplay_free(*info);
(*info) = NULL;
}
if (tcount == 0) {
for (i = 0; i < me->num_tracks; i++) {
- if ((*info)[i]->records != NULL) free((*info)[i]->records);
+ if ((*info)[i]->records != NULL)
+ oggplay_free((*info)[i]->records);
}
- free(*info);
+ oggplay_free(*info);
(*info) = NULL;
}
@@ -299,10 +314,10 @@ oggplay_callback_info_destroy(OggPlay *me, OggPlayCallbackInfo **info) {
for (i = 0; i < me->num_tracks; i++) {
p = info[i];
if (me->buffer == NULL && p->records != NULL)
- free(p->records);
+ oggplay_free(p->records);
}
- free(info);
+ oggplay_free(info);
}
diff --git a/src/liboggplay/oggplay_data.c b/src/liboggplay/oggplay_data.c
index 3055f0e..0bf7651 100644
--- a/src/liboggplay/oggplay_data.c
+++ b/src/liboggplay/oggplay_data.c
@@ -157,7 +157,7 @@ oggplay_data_add_to_list (OggPlayDecode *decode, OggPlayDataHeader *data) {
if (untimed->presentation_time >= decode->player->presentation_time) {
oggplay_data_add_to_list_front(decode, untimed);
} else {
- free(untimed);
+ oggplay_free(untimed);
}
}
@@ -188,7 +188,7 @@ oggplay_data_free_list(OggPlayDataHeader *list) {
while (list != NULL) {
p = list;
list = list->next;
- free(p);
+ oggplay_free(p);
}
}
@@ -236,13 +236,13 @@ oggplay_data_clean_list (OggPlayDecode *decode) {
decode->data_list = decode->data_list->next;
if (decode->data_list == NULL)
decode->end_of_data_list = NULL;
- free (header);
+ oggplay_free (header);
header = decode->data_list;
} else {
if (header->next == NULL)
decode->end_of_data_list = p;
p->next = header->next;
- free (header);
+ oggplay_free (header);
header = p->next;
}
} else {
@@ -271,12 +271,15 @@ oggplay_data_handle_audio_data (OggPlayDecode *decode, void *data,
int samples, int samplesize) {
int num_channels;
- OggPlayAudioRecord * record;
+ OggPlayAudioRecord * record = NULL;
num_channels = ((OggPlayAudioDecode *)decode)->sound_info.channels;
- record = (OggPlayAudioRecord*)calloc(sizeof(OggPlayAudioRecord) +
+ record = (OggPlayAudioRecord*)oggplay_calloc(sizeof(OggPlayAudioRecord) +
samples * samplesize * num_channels, 1);
+ if (record == NULL)
+ return;
+
oggplay_data_initialise_header(decode, &(record->header));
record->header.samples_in_record = samples;
@@ -295,10 +298,14 @@ void
oggplay_data_handle_cmml_data(OggPlayDecode *decode, unsigned char *data,
int size) {
- OggPlayTextRecord * record;
+ OggPlayTextRecord * record = NULL;
record =
- (OggPlayTextRecord*)calloc (sizeof(OggPlayTextRecord) + size + 1, 1);
+ (OggPlayTextRecord*)oggplay_calloc (sizeof(OggPlayTextRecord) + size + 1, 1);
+
+ if (record == NULL)
+ return;
+
oggplay_data_initialise_header(decode, &(record->header));
record->header.samples_in_record = 1;
@@ -336,7 +343,11 @@ oggplay_data_handle_theora_frame (OggPlayTheoraDecode *decode,
* we need to set the output strides to the input widths because we are
* trying not to pass negative output stride issues on to the poor user.
*/
- record = (OggPlayVideoRecord*)malloc (size);
+ record = (OggPlayVideoRecord*)oggplay_malloc (size);
+
+ if (record == NULL)
+ return;
+
record->header.samples_in_record = 1;
data = &(record->data);
oggplay_data_initialise_header((OggPlayDecode *)decode, &(record->header));
@@ -379,9 +390,13 @@ oggplay_data_handle_kate_data(OggPlayKateDecode *decode, const kate_event *ev) {
// TODO: should be able to send the data rendered as YUV data, but just text for now
- OggPlayTextRecord * record;
+ OggPlayTextRecord * record = NULL;
+
+ record = (OggPlayTextRecord*)oggplay_calloc (sizeof(OggPlayTextRecord) + ev->len0, 1);
+
+ if (record = NULL)
+ return;
- record = (OggPlayTextRecord*)calloc (sizeof(OggPlayTextRecord) + ev->len0, 1);
oggplay_data_initialise_header(&decode->decoder, &(record->header));
//record->header.presentation_time = (ogg_int64_t)(ev->start_time*1000);
diff --git a/src/liboggplay/oggplay_file_reader.c b/src/liboggplay/oggplay_file_reader.c
index 789049f..1ec0f42 100644
--- a/src/liboggplay/oggplay_file_reader.c
+++ b/src/liboggplay/oggplay_file_reader.c
@@ -76,7 +76,7 @@ oggplay_file_reader_destroy(OggPlayReader * opr) {
me = (OggPlayFileReader *)opr;
fclose(me->file);
- free(me);
+ oggplay_free(me);
return E_OGGPLAY_OK;
}
@@ -135,7 +135,10 @@ oggplay_file_reader_io_tell(void * user_handle) {
OggPlayReader *
oggplay_file_reader_new(char *file_name) {
- OggPlayFileReader * me = malloc (sizeof (OggPlayFileReader));
+ OggPlayFileReader * me = oggplay_malloc (sizeof (OggPlayFileReader));
+
+ if (me == NULL)
+ return NULL;
me->current_position = 0;
me->file_name = file_name;
diff --git a/src/liboggplay/oggplay_private.h b/src/liboggplay/oggplay_private.h
index c4743e6..7e5b9de 100644
--- a/src/liboggplay/oggplay_private.h
+++ b/src/liboggplay/oggplay_private.h
@@ -240,47 +240,15 @@ typedef struct {
int size;
} OggPlayCallbackFunctions;
+/* Allocate and free dynamic memory used by ogg.
+ * By default they are the ones from stdlib */
+#define oggplay_malloc _ogg_malloc
+#define oggplay_calloc _ogg_calloc
+#define oggplay_realloc _ogg_realloc
+#define oggplay_free _ogg_free
+
#include "oggplay_callback.h"
#include "oggplay_data.h"
#include "oggplay_buffer.h"
-#if 0
-static inline void _free(void *x) {
- printf("%p\n", x);
- free(x);
-}
-
-static inline void *_malloc(int s) {
- void *x;
- printf("%d ", s);
- x = malloc(s);
- printf("%p\n", x);
- return x;
-}
-
-static inline void *_realloc(void *x, int s) {
- void *y;
- printf("%p %d ", x, s);
- y = realloc(x, s);
- printf("%p\n", y);
- return y;
-}
-
-static inline void *_calloc(int n, int s) {
- void *x;
- printf("%d %d ", n, s);
- x = calloc(n, s);
- printf("%p\n", x);
- return x;
-}
-
-#define free(x) {printf("FREE %s %d ", __FILE__, __LINE__); _free(x);}
-#define malloc(s) (printf("MALLOC %s %d ", __FILE__, __LINE__), \
- _malloc(s))
-#define realloc(x, s) (printf("REALLOC %s %d ", __FILE__, __LINE__), \
- _realloc(x, s))
-#define calloc(n, s) (printf("CALLOC %s %d ", __FILE__, __LINE__), \
- _calloc(n, s))
-#endif
-
#endif
diff --git a/src/liboggplay/oggplay_seek.c b/src/liboggplay/oggplay_seek.c
index 415ce0f..f93552f 100644
--- a/src/liboggplay/oggplay_seek.c
+++ b/src/liboggplay/oggplay_seek.c
@@ -87,13 +87,19 @@ oggplay_seek_cleanup(OggPlay* me, ogg_int64_t milliseconds)
OggPlayDataHeader ** end_of_list_p;
int i;
+ if (me == NULL)
+ return;
+
/*
* first, create a trash object to store the context that we want to
* delete but can't until the presentation thread is no longer using it -
* this will occur as soon as the thread calls oggplay_buffer_release_next
*/
- trash = calloc(sizeof(OggPlaySeekTrash), 1);
+ trash = oggplay_calloc(1, sizeof(OggPlaySeekTrash));
+
+ if (trash == NULL)
+ return;
/*
* store the old buffer in it next.
@@ -106,6 +112,11 @@ oggplay_seek_cleanup(OggPlay* me, ogg_int64_t milliseconds)
*/
me->buffer = oggplay_buffer_new_buffer(me->buffer->buffer_size);
+ if (me->buffer == NULL)
+ {
+ return;
+ }
+
/*
* strip all of the data packets out of the streams and put them into the
* trash. We can free the untimed packets immediately - they are USELESS
@@ -152,12 +163,12 @@ oggplay_take_out_trash(OggPlay *me, OggPlaySeekTrash *trash) {
oggplay_buffer_shutdown(me, trash->old_buffer);
oggplay_data_free_list(trash->old_data);
if (p != NULL) {
- free(p);
+ oggplay_free(p);
}
p = trash;
}
if (p != NULL) {
- free(p);
+ oggplay_free(p);
}
}
diff --git a/src/liboggplay/oggplay_tcp_reader.c b/src/liboggplay/oggplay_tcp_reader.c
index c2d55fb..e40d2da 100644
--- a/src/liboggplay/oggplay_tcp_reader.c
+++ b/src/liboggplay/oggplay_tcp_reader.c
@@ -148,13 +148,21 @@ oggplay_create_socket() {
return sock;
}
-/*
- * this function guarantees it will return malloced versions of host and
+/**
+ * This function guarantees it will return malloced versions of host and
* path
+ *
+ * @param location Location of the Ogg content
+ * @param proxy The proxy if there's any.
+ * @param proxy_port The port of the proxy if there's any.
+ * @param host The host to connect to; using proxy if set.
+ * @param port The port to connect to;
+ * @param path The path where the content resides on the server.
+ * @retval -1 in case of error, 0 otherwise.
*/
-void
+int
oggplay_hostname_and_path(char *location, char *proxy, int proxy_port,
- char **host, int *port, char **path) {
+ char **host, int *port, char **path) {
char * colon;
@@ -163,10 +171,15 @@ oggplay_hostname_and_path(char *location, char *proxy, int proxy_port,
/* if we have a proxy installed this is all dead simple */
if (proxy != NULL) {
- *host = strdup(proxy);
+ if ((*host = strdup(proxy)) == NULL)
+ goto error;
+
*port = proxy_port;
- *path = strdup(location);
- return;
+
+ if ((*path = strdup(location)) == NULL)
+ goto error;
+
+ return 0;
}
/* find start_pos */
@@ -181,10 +194,15 @@ oggplay_hostname_and_path(char *location, char *proxy, int proxy_port,
* if both are null, then just set the simple defaults and return
*/
if (colon == NULL && slash == NULL) {
- *host = strdup(location);
+ if ((*host = strdup(location)) == NULL)
+ goto error;
+
*port = 80;
- *path = strdup("/");
- return;
+
+ if ((*path = strdup("/") == NULL))
+ goto error;
+
+ return 0;
}
/*
@@ -208,16 +226,29 @@ oggplay_hostname_and_path(char *location, char *proxy, int proxy_port,
end_of_host = slash;
}
- *host = strdup(location);
+ if ((*host = strdup(location)) == NULL)
+ goto error;
+
(*host)[end_of_host - location] = '\0';
if (slash == NULL) {
- *path = strdup("/");
- return;
+ if ((*path = strdup("/")) == NULL)
+ goto error;
+
+ return 0;
}
- *path = strdup(slash);
+ if ((*path = strdup(slash)) == NULL)
+ goto error;
+
+ return 0;
+
+error:
+ /* there has been an error while copying strings... */
+ if (*host != NULL)
+ oggplay_free(*host);
+ return -1;
}
OggPlayErrorCode
@@ -303,8 +334,9 @@ oggplay_tcp_reader_initialise(OggPlayReader * opr, int block) {
/*
* Extract the host name and the path from the location.
*/
- oggplay_hostname_and_path(me->location, me->proxy, me->proxy_port,
- &host, &port, &path);
+ if (oggplay_hostname_and_path(me->location, me->proxy, me->proxy_port,
+ &host, &port, &path) != 0)
+ return E_OGGPLAY_OUT_OF_MEMORY;
/*
@@ -320,8 +352,8 @@ oggplay_tcp_reader_initialise(OggPlayReader * opr, int block) {
he = gethostbyname(host);
- free(host);
- free(path);
+ oggplay_free(host);
+ oggplay_free(path);
if (he == NULL) {
printf("Host not found\n");
@@ -374,7 +406,10 @@ oggplay_tcp_reader_initialise(OggPlayReader * opr, int block) {
int found_http_response = 0;
if (me->buffer == NULL) {
- me->buffer = (unsigned char*)malloc(TCP_READER_MAX_IN_MEMORY);
+ me->buffer = (unsigned char*)oggplay_malloc(TCP_READER_MAX_IN_MEMORY);
+ if (me->buffer == NULL)
+ return E_OGGPLAY_OUT_OF_MEMORY;
+
me->buffer_size = TCP_READER_MAX_IN_MEMORY;
me->amount_in_memory = 0;
}
@@ -514,12 +549,12 @@ oggplay_tcp_reader_destroy(OggPlayReader * opr) {
#endif
}
- free(me->buffer);
- free(me->location);
+ if (me->buffer != NULL) oggplay_free(me->buffer);
+ if (me->location != NULL) oggplay_free(me->location);
if (me->backing_store != NULL) {
fclose(me->backing_store);
}
- free(me);
+ oggplay_free(me);
return E_OGGPLAY_OK;
}
@@ -661,14 +696,22 @@ oggplay_tcp_reader_io_tell(void * user_handle) {
OggPlayReader *
oggplay_tcp_reader_new(char *location, char *proxy, int proxy_port) {
- OggPlayTCPReader * me = (OggPlayTCPReader *)malloc (sizeof (OggPlayTCPReader));
+ OggPlayTCPReader * me = (OggPlayTCPReader *)oggplay_malloc (sizeof (OggPlayTCPReader));
+
+ if (me == NULL)
+ return NULL;
me->state = OTRS_UNINITIALISED;
me->socket = INVALID_SOCKET;
me->buffer = NULL;
me->buffer_size = 0;
me->current_position = 0;
- me->location = strdup(location);
+ /* if there's not enough memory to copy the URI cancel the initialisation */
+ if ( (me->location = strdup(location)) == NULL)
+ {
+ oggplay_tcp_reader_destroy ((OggPlayReader*)me);
+ return NULL;
+ }
me->amount_in_memory = 0;
me->backing_store = NULL;
me->stored_offset = 0;

Просмотреть файл

@ -1,23 +0,0 @@
commit b16896c4b4c77dcff5d77851e17ab2846372e935
Author: oggk <oggk@8158c8cd-e7e1-0310-9fa4-c5954c97daef>
Date: Tue Feb 24 23:19:59 2009 +0000
fix crucially misplaced parenthesis
git-svn-id: http://svn.annodex.net/liboggplay/trunk@3864 8158c8cd-e7e1-0310-9fa4-c5954c97daef
diff --git a/src/liboggplay/oggplay_tcp_reader.c b/src/liboggplay/oggplay_tcp_reader.c
index e40d2da..3becb6d 100644
--- a/src/liboggplay/oggplay_tcp_reader.c
+++ b/src/liboggplay/oggplay_tcp_reader.c
@@ -199,7 +199,7 @@ oggplay_hostname_and_path(char *location, char *proxy, int proxy_port,
*port = 80;
- if ((*path = strdup("/") == NULL))
+ if ((*path = strdup("/")) == NULL)
goto error;
return 0;

Просмотреть файл

@ -1,62 +0,0 @@
Index: /liboggplay/trunk/src/liboggplay/std_semaphore.h
===================================================================
--- /liboggplay/trunk/src/liboggplay/std_semaphore.h (revision 3756)
+++ /liboggplay/trunk/src/liboggplay/std_semaphore.h (revision 3871)
@@ -35,4 +35,44 @@
#ifndef _STD_SEMAPHORE_H
#define _STD_SEMAPHORE_H
+
+/**
+ * @def SEM_CREATE(p,s)
+ *
+ * Macro that creates a semaphore.
+ *
+ * @param p semaphore handle
+ * @param s initial value of the semaphore
+ * @retval 0 on success
+ * @retval non-zero on error
+ */
+
+/**
+ * @def SEM_SIGNAL(p)
+ *
+ * The macro increments the given semaphore.
+ *
+ * @param p semaphore handle.
+ * @retval 0 on success
+ * @retval non-zero on error
+ */
+
+/**
+ * @def SEM_WAIT(p)
+ *
+ * Macro that decrements (locks) the semaphore.
+ *
+ * @param p semaphore handle
+ */
+
+/**
+ * @def SEM_CLOSE(p)
+ *
+ * Macro that closes a given semaphore.
+ *
+ * @param p semaphore handle
+ * @retval 0 on success
+ * @retval non-zero on error
+ */
+
#if defined(linux) || defined(SOLARIS)
#include <semaphore.h>
@@ -44,9 +84,8 @@
#elif defined(WIN32)
#include <windows.h>
-#define SEM_CREATE(p,s) p = CreateSemaphore(NULL, (long)(s), (long)(s), NULL)
-#define SEM_SIGNAL(p) ReleaseSemaphore(p, 1, NULL)
+#define SEM_CREATE(p,s) (!(p = CreateSemaphore(NULL, (long)(s), (long)(s), NULL)))
+#define SEM_SIGNAL(p) (!ReleaseSemaphore(p, 1, NULL))
#define SEM_WAIT(p) WaitForSingleObject(p, INFINITE)
-#define SEM_TEST(p,s) p = WaitForSingleObject(s, 0)
-#define SEM_CLOSE(p) CloseHandle(p)
+#define SEM_CLOSE(p) (!CloseHandle(p))
typedef HANDLE semaphore;
#elif defined(__APPLE__)

Просмотреть файл

@ -0,0 +1,241 @@
diff --git a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
--- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
+++ b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
@@ -55,32 +55,18 @@
#include "oggplay_yuv2rgb_x86.c"
#elif defined(__ppc__) || defined(__ppc64__)
//altivec intristics only working with -maltivec gcc flag,
//but we want runtime altivec detection, hence this has to be
//fixed!
//#include "oggplay_yuv2rgb_altivec.c"
#endif
-/**
- * yuv_convert_fptr type is a function pointer type for
- * the various yuv-rgb converters
- */
-typedef void (*yuv_convert_fptr) (const OggPlayYUVChannels *yuv,
- OggPlayRGBChannels *rgb);
-
-/* it is useless to determine each YUV conversion run
- * the cpu type/featurs, thus we save the conversion function
- * pointers
- */
-static struct OggPlayYUVConverters {
- yuv_convert_fptr yuv2rgba; /**< YUV420 to RGBA */
- yuv_convert_fptr yuv2bgra; /**< YUV420 to BGRA */
- yuv_convert_fptr yuv2argb; /**< YUV420 to ARGB */
-} yuv_conv = {NULL, NULL, NULL};
+static int yuv_initialized;
+static ogg_uint32_t cpu_features;
/**
* vanilla implementation of YUV-to-RGB conversion.
*
* - using table-lookups instead of multiplication
* - avoid CLAMPing by incorporating
*
*/
@@ -89,38 +75,42 @@ static struct OggPlayYUVConverters {
#define prec 15
static const int CoY = (int)(1.164 * (1 << prec) + 0.5);
static const int CoRV = (int)(1.596 * (1 << prec) + 0.5);
static const int CoGU = (int)(0.391 * (1 << prec) + 0.5);
static const int CoGV = (int)(0.813 * (1 << prec) + 0.5);
static const int CoBU = (int)(2.018 * (1 << prec) + 0.5);
-static int CoefsGU[256] = {0};
+static int CoefsGU[256];
static int CoefsGV[256];
static int CoefsBU[256];
static int CoefsRV[256];
static int CoefsY[256];
/**
- * Initialize the lookup-table for vanilla yuv to rgb conversion.
+ * Initialize the lookup-table for vanilla yuv to rgb conversion
+ * and the cpu_features global.
*/
static void
-init_tables()
+init_yuv_converters()
{
int i;
for(i = 0; i < 256; ++i)
{
CoefsGU[i] = -CoGU * (i - 128);
CoefsGV[i] = -CoGV * (i - 128);
CoefsBU[i] = CoBU * (i - 128);
CoefsRV[i] = CoRV * (i - 128);
CoefsY[i] = CoY * (i - 16) + (prec/2);
}
+
+ cpu_features = oc_cpu_flags_get();
+ yuv_initialized = 1;
}
#define VANILLA_YUV2RGB_PIXEL(y, ruv, guv, buv) \
r = (CoefsY[y] + ruv) >> prec; \
g = (CoefsY[y] + guv) >> prec; \
b = (CoefsY[y] + buv) >> prec; \
#define VANILLA_RGBA_OUT(out, r, g, b) \
@@ -164,102 +154,83 @@ out[3] = CLAMP(r);
YUV_CONVERT(yuv420_to_rgba_vanilla, CONVERT(VANILLA_RGBA_OUT), 2, 8, 2, 1)
YUV_CONVERT(yuv420_to_bgra_vanilla, CONVERT(VANILLA_BGRA_OUT), 2, 8, 2, 1)
YUV_CONVERT(yuv420_to_abgr_vanilla, CONVERT(VANILLA_ABGR_OUT), 2, 8, 2, 1)
YUV_CONVERT(yuv420_to_argb_vanilla, CONVERT(VANILLA_ARGB_OUT), 2, 8, 2, 1)
#undef CONVERT
#undef CLEANUP
-/**
- * Initialize the function pointers in yuv_conv.
- *
- * Initialize the function pointers in yuv_conv, based on the
- * the available CPU extensions.
- */
-static void
-init_yuv_converters(void)
-{
- ogg_uint32_t features = 0;
-
- if ( yuv_conv.yuv2rgba == NULL )
- {
- features = oc_cpu_flags_get();
-#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
-#if defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16
- if (features & (OC_CPU_X86_SSE2|OC_CPU_X86_MMX|OC_CPU_X86_SSE))
- {
- yuv_conv.yuv2rgba = yuv420_to_rgba_sse2;
- yuv_conv.yuv2bgra = yuv420_to_bgra_sse2;
- yuv_conv.yuv2argb = yuv420_to_argb_sse2;
- return;
- }
- else
-#endif /* ATTRIBUTE_ALIGNED_MAX */
- if (features & (OC_CPU_X86_MMX|OC_CPU_X86_SSE))
- {
- yuv_conv.yuv2rgba = yuv420_to_rgba_mmx;
- yuv_conv.yuv2bgra = yuv420_to_bgra_mmx;
- yuv_conv.yuv2argb = yuv420_to_argb_mmx;
- return;
- }
- else if (features & OC_CPU_X86_MMX)
- {
- yuv_conv.yuv2rgba = yuv420_to_rgba_mmx;
- yuv_conv.yuv2bgra = yuv420_to_bgra_mmx;
- yuv_conv.yuv2argb = yuv420_to_argb_mmx;
- return;
- }
-#elif defined(__ppc__) || defined(__ppc64__)
- if (features & OC_CPU_PPC_ALTIVEC)
- {
- init_tables();
- yuv_conv.yuv2rgba = yuv420_to_abgr_vanilla;
- yuv_conv.yuv2bgra = yuv420_to_argb_vanilla;
- yuv_conv.yuv2argb = yuv420_to_bgra_vanilla;
- return;
- }
-#endif
- /*
- * no CPU extension was found... using vanilla converter, with respect
- * to the endianness of the host
- */
- init_tables();
-#if WORDS_BIGENDIAN || IS_BIG_ENDIAN
- yuv_conv.yuv2rgba = yuv420_to_abgr_vanilla;
- yuv_conv.yuv2bgra = yuv420_to_argb_vanilla;
- yuv_conv.yuv2argb = yuv420_to_bgra_vanilla;
-#else
- yuv_conv.yuv2rgba = yuv420_to_rgba_vanilla;
- yuv_conv.yuv2bgra = yuv420_to_bgra_vanilla;
- yuv_conv.yuv2argb = yuv420_to_argb_vanilla;
-#endif
- }
-}
-
-
void
oggplay_yuv2rgba(const OggPlayYUVChannels* yuv, OggPlayRGBChannels* rgb)
{
- if (yuv_conv.yuv2rgba == NULL)
+ if (!yuv_initialized)
init_yuv_converters();
- yuv_conv.yuv2rgba(yuv, rgb);
+#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
+#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
+ if (yuv->y_width % 16 == 0 && cpu_features & OC_CPU_X86_SSE2)
+ return yuv420_to_rgba_sse2(yuv, rgb);
+#endif
+ if (yuv->y_width % 8 == 0 && cpu_features & OC_CPU_X86_MMX)
+ return yuv420_to_rgba_mmx(yuv, rgb);
+#elif defined(__ppc__) || defined(__ppc64__)
+ if (yuv->y_width % 16 == 0 && yuv->y_height % 2 == 0 && cpu_features & OC_CPU_PPC_ALTIVEC)
+ return yuv420_to_abgr_vanilla(yuv, rgb);
+#endif
+
+#if WORDS_BIGENDIAN || IS_BIG_ENDIAN
+ return yuv420_to_abgr_vanilla(yuv, rgb);
+#else
+ return yuv420_to_rgba_vanilla(yuv, rgb);
+#endif
}
void
oggplay_yuv2bgra(const OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb)
{
- if (yuv_conv.yuv2bgra == NULL)
+ if (!yuv_initialized)
init_yuv_converters();
- yuv_conv.yuv2bgra(yuv, rgb);
+#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
+#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
+ if (yuv->y_width % 16 == 0 && cpu_features & OC_CPU_X86_SSE2)
+ return yuv420_to_bgra_sse2(yuv, rgb);
+#endif
+ if (yuv->y_width % 8 == 0 && cpu_features & OC_CPU_X86_MMX)
+ return yuv420_to_bgra_mmx(yuv, rgb);
+#elif defined(__ppc__) || defined(__ppc64__)
+ if (yuv->y_width % 16 == 0 && yuv->y_height % 2 == 0 && cpu_features & OC_CPU_PPC_ALTIVEC)
+ return yuv420_to_argb_vanilla(yuv, rgb);
+#endif
+
+#if WORDS_BIGENDIAN || IS_BIG_ENDIAN
+ return yuv420_to_argb_vanilla(yuv, rgb);
+#else
+ return yuv420_to_bgra_vanilla(yuv, rgb);
+#endif
}
void
oggplay_yuv2argb(const OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb)
{
- if (yuv_conv.yuv2argb == NULL)
+ if (!yuv_initialized)
init_yuv_converters();
- yuv_conv.yuv2argb(yuv, rgb);
+#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
+#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
+ if (yuv->y_width % 16 == 0 && cpu_features & OC_CPU_X86_SSE2)
+ return yuv420_to_argb_sse2(yuv, rgb);
+#endif
+ if (yuv->y_width % 8 == 0 && cpu_features & OC_CPU_X86_MMX)
+ return yuv420_to_argb_mmx(yuv, rgb);
+#elif defined(__ppc__) || defined(__ppc64__)
+ if (yuv->y_width % 16 == 0 && yuv->y_height % 2 == 0 && cpu_features & OC_CPU_PPC_ALTIVEC)
+ return yuv420_to_bgra_vanilla(yuv, rgb);
+#endif
+
+#if WORDS_BIGENDIAN || IS_BIG_ENDIAN
+ return yuv420_to_bgra_vanilla(yuv, rgb);
+#else
+ return yuv420_to_argb_vanilla(yuv, rgb);
+#endif
}

Просмотреть файл

@ -2,37 +2,37 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 0
/* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 0
/* #undef HAVE_INTTYPES_H */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 0
/* #undef HAVE_MEMORY_H */
/* Define if have liboggz */
#define HAVE_OGGZ
#define HAVE_OGGZ 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 0
/* #undef HAVE_STDINT_H */
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 0
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 0
/* #undef HAVE_SYS_STAT_H */
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 0
/* #undef HAVE_SYS_TYPES_H */
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 0
/* #undef HAVE_UNISTD_H */
/* Name of package */
#define PACKAGE "liboggplay"
@ -73,3 +73,6 @@
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Maximum supported data alignment */
/* #undef ATTRIBUTE_ALIGNED_MAX */

Просмотреть файл

@ -93,6 +93,9 @@ oggplay_set_data_callback(OggPlay *me, OggPlayDataCallback callback,
OggPlayErrorCode
oggplay_set_callback_num_frames(OggPlay *me, int stream, int frames);
OggPlayErrorCode
oggplay_set_callback_period(OggPlay *me, int stream, int milliseconds);
OggPlayErrorCode
oggplay_set_offset(OggPlay *me, int track, ogg_int64_t offset);
@ -111,12 +114,21 @@ oggplay_get_audio_samplerate(OggPlay *me, int track, int *samplerate);
OggPlayErrorCode
oggplay_get_video_fps(OggPlay *me, int track, int* fps_denom, int* fps_num);
OggPlayErrorCode
oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert);
OggPlayErrorCode
oggplay_get_kate_category(OggPlay *me, int track, const char** category);
OggPlayErrorCode
oggplay_get_kate_language(OggPlay *me, int track, const char** language);
OggPlayErrorCode
oggplay_set_kate_tiger_rendering(OggPlay *me, int track, int use_tiger);
OggPlayErrorCode
oggplay_overlay_kate_track_on_video(OggPlay *me, int kate_track, int video_track);
OggPlayErrorCode
oggplay_start_decoding(OggPlay *me);

Просмотреть файл

@ -45,6 +45,14 @@ typedef struct {
unsigned char * v;
} OggPlayVideoData;
typedef struct {
unsigned char * rgba; /* may be NULL if no alpha */
unsigned char * rgb; /* may be NULL if alpha */
size_t width; /* in pixels */
size_t height; /* in pixels */
size_t stride; /* in bytes */
} OggPlayOverlayData;
typedef void * OggPlayAudioData;
typedef char OggPlayTextData;
@ -67,6 +75,9 @@ oggplay_callback_info_get_record_size(OggPlayDataHeader *header);
OggPlayVideoData *
oggplay_callback_info_get_video_data(OggPlayDataHeader *header);
OggPlayOverlayData *
oggplay_callback_info_get_overlay_data(OggPlayDataHeader *header);
OggPlayAudioData *
oggplay_callback_info_get_audio_data(OggPlayDataHeader *header);

Просмотреть файл

@ -62,13 +62,15 @@ typedef enum OggPlayErrorCode {
E_OGGPLAY_TIMEOUT = -17,
E_OGGPLAY_CANT_SEEK = -18,
E_OGGPLAY_NO_KATE_SUPPORT = -19,
E_OGGPLAY_OUT_OF_MEMORY = -20,
E_OGGPLAY_NO_TIGER_SUPPORT = -20,
E_OGGPLAY_OUT_OF_MEMORY = -21,
E_OGGPLAY_NOTCHICKENPAYBACK = -777
} OggPlayErrorCode;
typedef enum OggPlayDataType {
OGGPLAY_INACTIVE = -1,
OGGPLAY_YUV_VIDEO = 0,
OGGPLAY_RGBA_VIDEO = 1,
OGGPLAY_SHORTS_AUDIO = 1000,
OGGPLAY_FLOATS_AUDIO = 1001,
OGGPLAY_CMML = 2000,

Просмотреть файл

@ -72,13 +72,13 @@ typedef struct _OggPlayRGBChannels {
} OggPlayRGBChannels;
void
oggplay_yuv2rgb(OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb);
oggplay_yuv2rgba(const OggPlayYUVChannels *yuv, OggPlayRGBChannels * rgb);
void
oggplay_yuv2argb(OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb);
oggplay_yuv2bgra(const OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb);
void
oggplay_yuv2bgr(OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb);
void
oggplay_yuv2argb(const OggPlayYUVChannels *yuv, OggPlayRGBChannels * rgb);
ogg_int64_t
oggplay_sys_time_in_ms(void);

Просмотреть файл

@ -1,14 +1,23 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Maximum supported data alignment */
/* Define to 1 if you have the `assert' function. */
/* #undef HAVE_ASSERT */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define if have libfishsound */
#define HAVE_FISHSOUND
#define HAVE_FISHSOUND /**/
/* Define if we have GLUT. */
#define HAVE_GLUT
#define HAVE_GLUT /**/
/* Define if have Imlib2 */
/* #undef HAVE_IMLIB2 */
@ -20,13 +29,13 @@
/* #undef HAVE_KATE */
/* Define if have libsndfile */
/* #undef HAVE_LIBSNDFILE1 */
#define HAVE_LIBSNDFILE1 /**/
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if have liboggz */
#define HAVE_OGGZ
#define HAVE_OGGZ /**/
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
@ -46,9 +55,16 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define if have libtiger */
/* #undef HAVE_TIGER */
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */
@ -76,18 +92,18 @@
/* Version number of package */
#define VERSION "0.0.1"
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* use MMX SSE2 compiler intrinsics */
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
#undef HAVE_GLUT
#include "prcpucfg.h"
#ifdef IS_BIG_ENDIAN
#define WORDS_BIGENDIAN
#endif

Просмотреть файл

@ -0,0 +1,270 @@
/********************************************************************
* *
* THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2008 *
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
* *
********************************************************************
CPU capability detection for x86 processors.
Originally written by Rudolf Marek.
function:
last mod: $Id$
********************************************************************/
#include "cpu.h"
/* for detecting AltiVec support */
# if (defined(__ppc__) || defined(__ppc64__))
# if defined(__APPLE__) || defined(__MACOSX__)
#include <sys/sysctl.h>
# else
#include <signal.h>
#include <setjmp.h>
# endif
# endif
# if (defined(__ppc__) || defined(__ppc64__)) && !(defined(__APPLE__) || defined(__MACOSX__))
static jmp_buf jmpbuf;
static void illegal_instruction(int sig)
{
longjmp(jmpbuf, 1);
}
# endif
# if !defined(_MSC_VER)
# if defined(__amd64__)||defined(__x86_64__)
/*On x86-64, gcc seems to be able to figure out how to save %rbx for us when
compiling with -fPIC.*/
# define cpuid(_op,_eax,_ebx,_ecx,_edx) \
__asm__ __volatile__( \
"cpuid\n\t" \
:[eax]"=a"(_eax),[ebx]"=b"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \
:"a"(_op) \
:"cc" \
)
# else
/*On x86-32, not so much.*/
# define cpuid(_op,_eax,_ebx,_ecx,_edx) \
__asm__ __volatile__( \
"xchgl %%ebx,%[ebx]\n\t" \
"cpuid\n\t" \
"xchgl %%ebx,%[ebx]\n\t" \
:[eax]"=a"(_eax),[ebx]"=r"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \
:"a"(_op) \
:"cc" \
)
# endif
# else
/*Why does MSVC need this complicated rigamarole?
At this point I honestly do not care.*/
/*Visual C cpuid helper function.
For VS2005 we could as well use the _cpuid builtin, but that wouldn't work
for VS2003 users, so we do it in inline assembler.*/
static void oc_cpuid_helper(ogg_uint32_t _cpu_info[4],ogg_uint32_t _op){
_asm {
mov eax,[_op]
mov esi,_cpu_info
cpuid
mov [esi+0],eax
mov [esi+4],ebx
mov [esi+8],ecx
mov [esi+12],edx
}
}
# define cpuid(_op,_eax,_ebx,_ecx,_edx) \
do{ \
ogg_uint32_t cpu_info[4]; \
oc_cpuid_helper(cpu_info,_op); \
(_eax)=cpu_info[0]; \
(_ebx)=cpu_info[1]; \
(_ecx)=cpu_info[2]; \
(_edx)=cpu_info[3]; \
}while(0)
static void oc_detect_cpuid_helper(ogg_uint32_t *_eax,ogg_uint32_t *_ebx){
_asm{
pushfd
pushfd
pop eax
mov ebx,eax
xor eax,200000h
push eax
popfd
pushfd
pop eax
popfd
mov ecx,_eax
mov [ecx],eax
mov ecx,_ebx
mov [ecx],ebx
}
}
# endif
static ogg_uint32_t oc_parse_intel_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){
ogg_uint32_t flags;
/*If there isn't even MMX, give up.*/
if(!(_edx&0x00800000))return 0;
flags=OC_CPU_X86_MMX;
if(_edx&0x02000000)flags|=OC_CPU_X86_MMXEXT|OC_CPU_X86_SSE;
if(_edx&0x04000000)flags|=OC_CPU_X86_SSE2;
if(_ecx&0x00000001)flags|=OC_CPU_X86_PNI;
if(_ecx&0x00000100)flags|=OC_CPU_X86_SSSE3;
if(_ecx&0x00080000)flags|=OC_CPU_X86_SSE4_1;
if(_ecx&0x00100000)flags|=OC_CPU_X86_SSE4_2;
return flags;
}
static ogg_uint32_t oc_parse_amd_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){
ogg_uint32_t flags;
/*If there isn't even MMX, give up.*/
if(!(_edx&0x00800000))return 0;
flags=OC_CPU_X86_MMX;
if(_edx&0x00400000)flags|=OC_CPU_X86_MMXEXT;
if(_edx&0x80000000)flags|=OC_CPU_X86_3DNOW;
if(_edx&0x40000000)flags|=OC_CPU_X86_3DNOWEXT;
if(_ecx&0x00000040)flags|=OC_CPU_X86_SSE4A;
if(_ecx&0x00000800)flags|=OC_CPU_X86_SSE5;
return flags;
}
static ogg_uint32_t oc_cpu_flags_get(void){
ogg_uint32_t flags = 0;
# if defined(__ppc__) || defined(__ppc64__)
/* detect AltiVec extension if compiling it for ppc */
# if defined(__APPLE__) || defined(__MACOSX__) || defined(__DARWIN__)
int selectors[2] = { CTL_HW, HW_VECTORUNIT };
int i_has_altivec = 0;
size_t i_length = sizeof( i_has_altivec );
int i_error = sysctl( selectors, 2, &i_has_altivec, &i_length, NULL, 0);
if( i_error == 0 && i_has_altivec != 0 )
flags |= OC_CPU_PPC_ALTIVEC;
# else
void (*handler) (int sig);
handler = signal(SIGILL, illegal_instruction);
if (setjmp(jmpbuf) == 0)
{
__asm__ __volatile__ (
"mtspr 256, %0\n\t"
"vand %%v0, %%v0, %%v0"
: : "r"(-1) );
flags |= OC_CPU_PPC_ALTIVEC;
}
signal(SIGILL, handler);
# endif
/* detect x86 CPU extensions */
# elif defined(i386) || defined(__x86_64__) || defined(_M_IX86)
ogg_uint32_t eax;
ogg_uint32_t ebx;
ogg_uint32_t ecx;
ogg_uint32_t edx;
# if !defined(__amd64__)&&!defined(__x86_64__)
/*Not all x86-32 chips support cpuid, so we have to check.*/
# if !defined(_MSC_VER)
__asm__ __volatile__(
"pushfl\n\t"
"pushfl\n\t"
"popl %[a]\n\t"
"movl %[a],%[b]\n\t"
"xorl $0x200000,%[a]\n\t"
"pushl %[a]\n\t"
"popfl\n\t"
"pushfl\n\t"
"popl %[a]\n\t"
"popfl\n\t"
:[a]"=r"(eax),[b]"=r"(ebx)
:
:"cc"
);
# else
oc_detect_cpuid_helper(&eax,&ebx);
# endif
/*No cpuid.*/
if(eax==ebx)return 0;
# endif
cpuid(0,eax,ebx,ecx,edx);
/* l e t n I e n i u n e G*/
if((ecx==0x6C65746E&&edx==0x49656E69&&ebx==0x756E6547)||
/* 6 8 x M T e n i u n e G*/
(ecx==0x3638784D&&edx==0x54656E69&&ebx==0x756E6547)) {
/*Intel, Transmeta (tested with Crusoe TM5800):*/
cpuid(1,eax,ebx,ecx,edx);
flags=oc_parse_intel_flags(edx,ecx);
}
/* D M A c i t n e h t u A*/
else if((ecx==0x444D4163&&edx==0x69746E65&&ebx==0x68747541)||
/* C S N y b e d o e G*/
(ecx==0x43534E20&&edx==0x79622065&&ebx==0x646F6547)){
/*AMD, Geode:*/
cpuid(0x80000000,eax,ebx,ecx,edx);
if(eax<0x80000001)flags=0;
else{
cpuid(0x80000001,eax,ebx,ecx,edx);
flags=oc_parse_amd_flags(edx,ecx);
}
/*Also check for SSE.*/
cpuid(1,eax,ebx,ecx,edx);
flags|=oc_parse_intel_flags(edx,ecx);
}
/*Technically some VIA chips can be configured in the BIOS to return any
string here the user wants.
There is a special detection method that can be used to identify such
processors, but in my opinion, if the user really wants to change it, they
deserve what they get.*/
/* s l u a H r u a t n e C*/
else if(ecx==0x736C7561&&edx==0x48727561&&ebx==0x746E6543){
/*VIA:*/
/*I only have documentation for the C7 (Esther) and Isaiah (forthcoming)
chips (thanks to the engineers from Centaur Technology who provided it).
These chips support Intel-like cpuid info.
The C3-2 (Nehemiah) cores appear to, as well.*/
cpuid(1,eax,ebx,ecx,edx);
flags=oc_parse_intel_flags(edx,ecx);
cpuid(0x80000000,eax,ebx,ecx,edx);
if(eax>=0x80000001){
/*The (non-Nehemiah) C3 processors support AMD-like cpuid info.
We need to check this even if the Intel test succeeds to pick up 3DNow!
support on these processors.
Unlike actual AMD processors, we cannot _rely_ on this info, since
some cores (e.g., the 693 stepping of the Nehemiah) claim to support
this function, yet return edx=0, despite the Intel test indicating
MMX support.
Therefore the features detected here are strictly added to those
detected by the Intel test.*/
/*TODO: How about earlier chips?*/
cpuid(0x80000001,eax,ebx,ecx,edx);
/*Note: As of the C7, this function returns Intel-style extended feature
flags, not AMD-style.
Currently, this only defines bits 11, 20, and 29 (0x20100800), which
do not conflict with any of the AMD flags we inspect.
For the remaining bits, Intel tells us, "Do not count on their value",
but VIA assures us that they will all be zero (at least on the C7 and
Isaiah chips).
In the (unlikely) event a future processor uses bits 18, 19, 30, or 31
(0xC0C00000) for something else, we will have to add code to detect
the model to decide when it is appropriate to inspect them.*/
flags|=oc_parse_amd_flags(edx,ecx);
}
}
else{
/*Implement me.*/
flags=0;
}
# else
/* not x86 or ppc */
# endif
return flags;
}

Просмотреть файл

@ -0,0 +1,34 @@
/********************************************************************
* *
* THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007 *
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
* *
********************************************************************
function:
last mod: $Id$
********************************************************************/
#ifndef __CPU_H__
#define __CPU_H__
#define OC_CPU_X86_MMX (1<<0)
#define OC_CPU_X86_3DNOW (1<<1)
#define OC_CPU_X86_3DNOWEXT (1<<2)
#define OC_CPU_X86_MMXEXT (1<<3)
#define OC_CPU_X86_SSE (1<<4)
#define OC_CPU_X86_SSE2 (1<<5)
#define OC_CPU_X86_PNI (1<<6)
#define OC_CPU_X86_SSSE3 (1<<7)
#define OC_CPU_X86_SSE4_1 (1<<8)
#define OC_CPU_X86_SSE4_2 (1<<9)
#define OC_CPU_X86_SSE4A (1<<10)
#define OC_CPU_X86_SSE5 (1<<11)
#define OC_CPU_PPC_ALTIVEC (1<<12)
#endif

Просмотреть файл

@ -218,10 +218,24 @@ oggplay_set_callback_num_frames(OggPlay *me, int track, int frames) {
me->callback_period = me->decode_data[track]->granuleperiod * frames;
me->target = me->presentation_time + me->callback_period - 1;
// printf("targ: %lld, callback_per: %lld, prestime: %lld\n", me->target, me->callback_period,me->presentation_time );
return E_OGGPLAY_OK;
}
OggPlayErrorCode
oggplay_set_callback_period(OggPlay *me, int track, int milliseconds) {
if (me == NULL) {
return E_OGGPLAY_BAD_OGGPLAY;
}
if (track < 0 || track >= me->num_tracks) {
return E_OGGPLAY_BAD_TRACK;
}
me->callback_period = OGGPLAY_TIME_INT_TO_FP(((ogg_int64_t)milliseconds))/1000;
me->target = me->presentation_time + me->callback_period - 1;
return E_OGGPLAY_OK;
}
OggPlayErrorCode
@ -231,11 +245,11 @@ oggplay_set_offset(OggPlay *me, int track, ogg_int64_t offset) {
return E_OGGPLAY_BAD_OGGPLAY;
}
if (track <= 0 || track > me->num_tracks) {
if (track < 0 || track >= me->num_tracks) {
return E_OGGPLAY_BAD_TRACK;
}
me->decode_data[track]->offset = (offset << 32) / 1000;
me->decode_data[track]->offset = OGGPLAY_TIME_INT_TO_FP(offset) / 1000;
return E_OGGPLAY_OK;
@ -270,6 +284,36 @@ oggplay_get_video_fps(OggPlay *me, int track, int* fps_denom, int* fps_num) {
return E_OGGPLAY_OK;
}
OggPlayErrorCode
oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert) {
OggPlayTheoraDecode *decode;
if (me == NULL) {
return E_OGGPLAY_BAD_OGGPLAY;
}
if (track < 0 || track >= me->num_tracks) {
return E_OGGPLAY_BAD_TRACK;
}
if (me->decode_data[track]->content_type != OGGZ_CONTENT_THEORA) {
return E_OGGPLAY_WRONG_TRACK_TYPE;
}
decode = (OggPlayTheoraDecode *)(me->decode_data[track]);
if (decode->convert_to_rgb != convert) {
decode->convert_to_rgb = convert;
me->decode_data[track]->decoded_type = convert ? OGGPLAY_RGBA_VIDEO : OGGPLAY_YUV_VIDEO;
/* flush any records created with previous type */
oggplay_data_free_list(me->decode_data[track]->data_list);
me->decode_data[track]->data_list = NULL;
}
return E_OGGPLAY_OK;
}
OggPlayErrorCode
oggplay_get_video_y_size(OggPlay *me, int track, int *y_width, int *y_height) {
@ -331,7 +375,7 @@ oggplay_get_video_uv_size(OggPlay *me, int track, int *uv_width, int *uv_height)
}
int
OggPlayErrorCode
oggplay_get_audio_channels(OggPlay *me, int track, int* channels) {
OggPlayAudioDecode *decode;
@ -358,7 +402,7 @@ oggplay_get_audio_channels(OggPlay *me, int track, int* channels) {
}
int
OggPlayErrorCode
oggplay_get_audio_samplerate(OggPlay *me, int track, int* rate) {
OggPlayAudioDecode * decode;
@ -385,7 +429,7 @@ oggplay_get_audio_samplerate(OggPlay *me, int track, int* rate) {
}
int
OggPlayErrorCode
oggplay_get_kate_category(OggPlay *me, int track, const char** category) {
OggPlayKateDecode * decode;
@ -398,21 +442,24 @@ oggplay_get_kate_category(OggPlay *me, int track, const char** category) {
return E_OGGPLAY_BAD_TRACK;
}
if (me->decode_data[track]->decoded_type != OGGPLAY_KATE) {
if (me->decode_data[track]->content_type != OGGZ_CONTENT_KATE) {
return E_OGGPLAY_WRONG_TRACK_TYPE;
}
decode = (OggPlayKateDecode *)(me->decode_data[track]);
#ifdef HAVE_KATE
(*category) = decode->k.ki->category;
return E_OGGPLAY_OK;
if (decode->init) {
(*category) = decode->k.ki->category;
return E_OGGPLAY_OK;
}
else return E_OGGPLAY_UNINITIALISED;
#else
return E_OGGPLAY_NO_KATE_SUPPORT;
#endif
}
int
OggPlayErrorCode
oggplay_get_kate_language(OggPlay *me, int track, const char** language) {
OggPlayKateDecode * decode;
@ -425,15 +472,99 @@ oggplay_get_kate_language(OggPlay *me, int track, const char** language) {
return E_OGGPLAY_BAD_TRACK;
}
if (me->decode_data[track]->decoded_type != OGGPLAY_KATE) {
if (me->decode_data[track]->content_type != OGGZ_CONTENT_KATE) {
return E_OGGPLAY_WRONG_TRACK_TYPE;
}
decode = (OggPlayKateDecode *)(me->decode_data[track]);
#ifdef HAVE_KATE
(*language) = decode->k.ki->language;
if (decode->init) {
(*language) = decode->k.ki->language;
return E_OGGPLAY_OK;
}
else return E_OGGPLAY_UNINITIALISED;
#else
return E_OGGPLAY_NO_KATE_SUPPORT;
#endif
}
OggPlayErrorCode
oggplay_set_kate_tiger_rendering(OggPlay *me, int track, int use_tiger) {
OggPlayKateDecode * decode;
if (me == NULL) {
return E_OGGPLAY_BAD_OGGPLAY;
}
if (track < 0 || track >= me->num_tracks) {
return E_OGGPLAY_BAD_TRACK;
}
if (me->decode_data[track]->content_type != OGGZ_CONTENT_KATE) {
return E_OGGPLAY_WRONG_TRACK_TYPE;
}
decode = (OggPlayKateDecode *)(me->decode_data[track]);
#ifdef HAVE_KATE
#ifdef HAVE_TIGER
if (decode->init && decode->tr) {
decode->use_tiger = use_tiger;
decode->decoder.decoded_type = use_tiger ? OGGPLAY_RGBA_VIDEO : OGGPLAY_KATE;
return E_OGGPLAY_OK;
}
else return E_OGGPLAY_UNINITIALISED;
#else
return E_OGGPLAY_NO_TIGER_SUPPORT;
#endif
#else
return E_OGGPLAY_NO_KATE_SUPPORT;
#endif
}
OggPlayErrorCode
oggplay_overlay_kate_track_on_video(OggPlay *me, int kate_track, int video_track) {
OggPlayKateDecode * decode;
if (me == NULL) {
return E_OGGPLAY_BAD_OGGPLAY;
}
if (kate_track < 0 || kate_track >= me->num_tracks) {
return E_OGGPLAY_BAD_TRACK;
}
if (video_track < 0 || video_track >= me->num_tracks) {
return E_OGGPLAY_BAD_TRACK;
}
if (me->decode_data[kate_track]->content_type != OGGZ_CONTENT_KATE) {
return E_OGGPLAY_WRONG_TRACK_TYPE;
}
if (me->decode_data[kate_track]->decoded_type != OGGPLAY_RGBA_VIDEO) {
return E_OGGPLAY_WRONG_TRACK_TYPE;
}
if (me->decode_data[video_track]->content_type != OGGZ_CONTENT_THEORA) {
return E_OGGPLAY_WRONG_TRACK_TYPE;
}
if (me->decode_data[video_track]->decoded_type != OGGPLAY_RGBA_VIDEO) {
return E_OGGPLAY_WRONG_TRACK_TYPE;
}
decode = (OggPlayKateDecode *)(me->decode_data[kate_track]);
#ifdef HAVE_KATE
#ifdef HAVE_TIGER
decode->overlay_dest = video_track;
return E_OGGPLAY_OK;
#else
return E_OGGPLAY_NO_TIGER_SUPPORT;
#endif
#else
return E_OGGPLAY_NO_KATE_SUPPORT;
#endif
@ -634,6 +765,8 @@ oggplay_close(OggPlay *me) {
oggplay_buffer_shutdown(me, me->buffer);
}
oggplay_free(me->callback_info);
oggplay_free(me->decode_data);
oggplay_free(me);
return E_OGGPLAY_OK;

Просмотреть файл

@ -58,7 +58,7 @@ oggplay_buffer_new_buffer(int size) {
size = OGGPLAY_DEFAULT_BUFFER_SIZE;
}
buffer = (OggPlayBuffer*)oggplay_malloc(sizeof (OggPlayBuffer));
buffer = (OggPlayBuffer*)oggplay_calloc(1, sizeof (OggPlayBuffer));
if (buffer == NULL)
return NULL;

Просмотреть файл

@ -57,6 +57,7 @@ oggplay_init_theora(void *user_data) {
decoder->granulepos_seen = 0;
decoder->frame_delta = 0;
decoder->y_width = 0;
decoder->convert_to_rgb = 0;
decoder->decoder.decoded_type = OGGPLAY_YUV_VIDEO;
}
@ -254,12 +255,12 @@ oggplay_callback_skel (OGGZ * oggz, ogg_packet * op, long serialno,
bt_den = extract_int64(op->packet + 36);
if (pt_den != 0) {
decoder->presentation_time = (pt_num << 32) * 1000 / pt_den;
decoder->presentation_time = OGGPLAY_TIME_INT_TO_FP(pt_num) / pt_den;
} else {
decoder->presentation_time = 0;
}
if (bt_den != 0) {
decoder->base_time = (bt_num << 32) / bt_den;
decoder->base_time = OGGPLAY_TIME_INT_TO_FP(bt_num) / bt_den;
} else {
decoder->base_time = 0;
}
@ -383,10 +384,33 @@ void
oggplay_init_kate(void *user_data) {
#ifdef HAVE_KATE
int ret;
OggPlayKateDecode * decoder = (OggPlayKateDecode *)user_data;
kate_high_decode_init(&(decoder->k));
decoder->init = 0;
ret = kate_high_decode_init(&(decoder->k));
if (ret < 0) {
/* what to do ? */
}
else {
decoder->init = 1;
}
decoder->decoder.decoded_type = OGGPLAY_KATE;
#ifdef HAVE_TIGER
decoder->use_tiger = 1;
decoder->overlay_dest = -1;
ret = tiger_renderer_create(&(decoder->tr));
if (ret < 0) {
/* what to do ? */
decoder->tr = NULL;
}
if (decoder->use_tiger) {
decoder->decoder.decoded_type = OGGPLAY_RGBA_VIDEO;
}
#endif
#endif
}
@ -396,7 +420,15 @@ oggplay_shutdown_kate(void *user_data) {
#ifdef HAVE_KATE
OggPlayKateDecode * decoder = (OggPlayKateDecode *)user_data;
kate_high_decode_clear(&(decoder->k));
#ifdef HAVE_TIGER
if (decoder->tr) {
tiger_renderer_destroy(decoder->tr);
}
#endif
if (decoder->init) {
kate_high_decode_clear(&(decoder->k));
}
#endif
}
@ -414,8 +446,15 @@ oggplay_callback_kate (OGGZ * oggz, ogg_packet * op, long serialno,
const kate_event *ev = NULL;
int ret;
if (!decoder->init) {
return E_OGGPLAY_UNINITIALISED;
}
kate_packet_wrap(&kp, op->bytes, op->packet);
ret = kate_high_decode_packetin(&(decoder->k), &kp, &ev);
if (ret < 0) {
return E_OGGPLAY_BAD_INPUT;
}
if (granulepos != -1) {
granuleshift = oggz_get_granuleshift(oggz, serialno);
@ -520,7 +559,7 @@ oggplay_initialise_decoder(OggPlay *me, int content_type, int serialno) {
* convert num and denom to a 32.32 fixed point value
*/
if (num != 0) {
decoder->granuleperiod = (denom << 32) / num;
decoder->granuleperiod = OGGPLAY_TIME_INT_TO_FP(denom) / num;
} else {
decoder->granuleperiod = 0;
}

Просмотреть файл

@ -38,8 +38,6 @@
#include "oggplay_private.h"
#include <stdlib.h>
#define M(x) ((x) >> 32)
extern void _print_list(char *name, OggPlayDataHeader *p);
int
@ -72,6 +70,24 @@ oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info) {
(*info)[i] = track_info;
#ifdef HAVE_TIGER
/* not so nice to have this here, but the tiger_renderer needs updating regularly
* as some items may be animated, so would yield data without the stream actually
* receiving any packets.
* In addition, Kate streams can now be overlayed on top of a video, so this needs
* calling to render the overlay.
* FIXME: is this the best place to put this ? Might do too much work if the info
* is going to be destroyed ?
*/
if (track->content_type == OGGZ_CONTENT_KATE) {
OggPlayKateDecode *decode = (OggPlayKateDecode *)track;
OggPlayCallbackInfo * video_info = NULL;
if (decode->overlay_dest >= 0)
video_info = me->callback_info + decode->overlay_dest;
oggplay_data_update_tiger(decode, track->active, me->target, video_info);
}
#endif
/*
* this track is inactive and has no data - create an empty record
* for it
@ -418,7 +434,7 @@ oggplay_callback_info_get_presentation_time(OggPlayDataHeader *header) {
}
/* SGS: is this correct? */
return (((header->presentation_time >> 16) * 1000) >> 16) & 0xFFFFFFFF;
return OGGPLAY_TIME_FP_TO_INT(header->presentation_time);
}
OggPlayVideoData *
@ -432,6 +448,17 @@ oggplay_callback_info_get_video_data(OggPlayDataHeader *header) {
}
OggPlayOverlayData *
oggplay_callback_info_get_overlay_data(OggPlayDataHeader *header) {
if (header == NULL) {
return NULL;
}
return &((OggPlayOverlayRecord *)header)->data;
}
OggPlayAudioData *
oggplay_callback_info_get_audio_data(OggPlayDataHeader *header) {

Просмотреть файл

@ -37,6 +37,7 @@
*/
#include "oggplay_private.h"
#include "oggplay/oggplay_callback_info.h"
#include <stdlib.h>
#include <string.h>
@ -92,8 +93,6 @@ oggplay_data_add_to_list_end(OggPlayDecode *decode, OggPlayDataHeader *data) {
}
#define M(x) ((x) >> 32)
/*
* helper function to append data packets to front of data_list
*/
@ -350,7 +349,6 @@ oggplay_data_handle_theora_frame (OggPlayTheoraDecode *decode,
record->header.samples_in_record = 1;
data = &(record->data);
oggplay_data_initialise_header((OggPlayDecode *)decode, &(record->header));
data->y = (unsigned char *)(record + 1);
data->u = data->y + (decode->y_stride * decode->y_height);
@ -381,31 +379,161 @@ oggplay_data_handle_theora_frame (OggPlayTheoraDecode *decode,
q2 += buffer->uv_stride;
}
oggplay_data_add_to_list((OggPlayDecode *)decode, &(record->header));
/* if we're to send RGB video, convert here */
if (decode->convert_to_rgb) {
OggPlayYUVChannels yuv;
OggPlayRGBChannels rgb;
OggPlayOverlayRecord * orecord;
OggPlayOverlayData * odata;
yuv.ptry = data->y;
yuv.ptru = data->u;
yuv.ptrv = data->v;
yuv.y_width = decode->y_width;
yuv.y_height = decode->y_height;
yuv.uv_width = decode->uv_width;
yuv.uv_height = decode->uv_height;
size = sizeof(OggPlayOverlayRecord) + decode->y_width * decode->y_height * 4;
orecord = (OggPlayOverlayRecord*) oggplay_malloc (size);
if (orecord) {
oggplay_data_initialise_header((OggPlayDecode *)decode, &(orecord->header));
orecord->header.samples_in_record = 1;
odata = &(orecord->data);
rgb.ptro = (unsigned char*)(orecord+1);
rgb.rgb_width = yuv.y_width;
rgb.rgb_height = yuv.y_height;
oggplay_yuv2rgba(&yuv, &rgb);
// odata->rgb = NULL;
// odata->rgba = rgb.ptro;
odata->rgb = rgb.ptro;
odata->rgba = NULL;
odata->width = rgb.rgb_width;
odata->height = rgb.rgb_height;
odata->stride = rgb.rgb_width*4;
oggplay_free(record);
oggplay_data_add_to_list((OggPlayDecode *)decode, &(orecord->header));
}
}
else {
oggplay_data_initialise_header((OggPlayDecode *)decode, &(record->header));
oggplay_data_add_to_list((OggPlayDecode *)decode, &(record->header));
}
}
#ifdef HAVE_KATE
void
oggplay_data_handle_kate_data(OggPlayKateDecode *decode, const kate_event *ev) {
// TODO: should be able to send the data rendered as YUV data, but just text for now
OggPlayTextRecord * record = NULL;
record = (OggPlayTextRecord*)oggplay_calloc (sizeof(OggPlayTextRecord) + ev->len0, 1);
if (record = NULL)
return;
#ifdef HAVE_TIGER
tiger_renderer_add_event(decode->tr, ev->ki, ev);
oggplay_data_initialise_header(&decode->decoder, &(record->header));
if (decode->use_tiger) {
/* if rendering with Tiger, we don't add an event, a synthetic one will be
generated each "tick" with an updated tracker state */
}
else
#endif
{
record = (OggPlayTextRecord*)oggplay_calloc (sizeof(OggPlayTextRecord) + ev->len0, 1);
if (!record)
return;
//record->header.presentation_time = (ogg_int64_t)(ev->start_time*1000);
record->header.samples_in_record = (ev->end_time-ev->start_time)*1000;
record->data = (char *)(record + 1);
oggplay_data_initialise_header(&decode->decoder, &(record->header));
memcpy(record->data, ev->text, ev->len0);
//record->header.presentation_time = (ogg_int64_t)(ev->start_time*1000);
record->header.samples_in_record = (ev->end_time-ev->start_time)*1000;
record->data = (char *)(record + 1);
oggplay_data_add_to_list(&decode->decoder, &(record->header));
memcpy(record->data, ev->text, ev->len0);
oggplay_data_add_to_list(&decode->decoder, &(record->header));
}
}
#endif
#ifdef HAVE_TIGER
void
oggplay_data_update_tiger(OggPlayKateDecode *decode, int active, ogg_int64_t presentation_time, OggPlayCallbackInfo *info) {
OggPlayOverlayRecord * record = NULL;
OggPlayOverlayData * data = NULL;
size_t size = sizeof (OggPlayOverlayRecord);
int track = active && decode->use_tiger;
kate_float t = OGGPLAY_TIME_FP_TO_INT(presentation_time) / 1000.0f;
if (!decode->init) return;
if (track) {
if (info) {
if (info->required_records>0) {
OggPlayDataHeader *header = info->records[0];
data = (OggPlayOverlayData*)(header+1);
if (decode->tr && data->rgb) {
tiger_renderer_set_buffer(decode->tr, data->rgb, data->width, data->height, data->stride, 1);
}
else {
/* we're supposed to overlay on a frame, but the available frame has no RGB buffer */
/* fprintf(stderr,"no RGB buffer found for video frame\n"); */
return;
}
}
else {
/* we're supposed to overlay on a frame, but there is no frame available */
/* fprintf(stderr,"no video frame to overlay on\n"); */
return;
}
}
else {
// TODO: some way of knowing the size of the video we'll be drawing onto, if any
int width = decode->k.ki->original_canvas_width;
int height = decode->k.ki->original_canvas_height;
if (width <= 0 || height <= 0) {
/* some default resolution if we're not overlaying onto a video and the canvas size is unknown */
width = 640;
height = 480;
}
size = sizeof (OggPlayOverlayRecord) + width*height*4;
record = (OggPlayOverlayRecord*)oggplay_calloc (1, size);
if (!record)
return;
record->header.samples_in_record = 1;
data= &(record->data);
oggplay_data_initialise_header((OggPlayDecode *)decode, &(record->header));
data->rgba = (unsigned char*)(record+1);
data->rgb = NULL;
data->width = width;
data->height = height;
data->stride = width*4;
if (decode->tr && data->rgba) {
tiger_renderer_set_buffer(decode->tr, data->rgba, data->width, data->height, data->stride, 1);
}
oggplay_data_add_to_list(&decode->decoder, &(record->header));
record->header.presentation_time=presentation_time;
}
}
if (decode->tr) {
tiger_renderer_update(decode->tr, t, track);
}
if (track) {
/* buffer was either calloced, so already cleared, or already filled with video, so no clearing */
if (decode->tr) {
tiger_renderer_render(decode->tr);
}
}
}
#endif

Просмотреть файл

@ -59,6 +59,13 @@ oggplay_data_handle_kate_data(OggPlayKateDecode *decode,
const kate_event *ev);
#endif
#ifdef HAVE_TIGER
void
oggplay_data_update_tiger(OggPlayKateDecode *decode,
int active, ogg_int64_t presentation_time,
OggPlayCallbackInfo *info);
#endif
void
oggplay_data_clean_list (OggPlayDecode *decode);

Просмотреть файл

@ -153,6 +153,7 @@ oggplay_file_reader_new(char *file_name) {
me->functions.io_read = &oggplay_file_reader_io_read;
me->functions.io_seek = &oggplay_file_reader_io_seek;
me->functions.io_tell = &oggplay_file_reader_io_tell;
me->functions.duration = NULL;
return (OggPlayReader *)me;

Просмотреть файл

@ -56,6 +56,9 @@
#ifdef HAVE_KATE
#include <kate/kate.h>
#endif
#ifdef HAVE_TIGER
#include <tiger/tiger.h>
#endif
#ifdef WIN32
@ -87,6 +90,11 @@ typedef struct {
OggPlayVideoData data;
} OggPlayVideoRecord;
typedef struct {
OggPlayDataHeader header;
OggPlayOverlayData data;
} OggPlayOverlayRecord;
typedef struct {
OggPlayDataHeader header;
void * data;
@ -171,6 +179,7 @@ typedef struct {
int uv_height;
int uv_stride;
int cached_keyframe;
int convert_to_rgb;
} OggPlayTheoraDecode;
typedef struct {
@ -195,6 +204,12 @@ typedef struct {
#ifdef HAVE_KATE
int granuleshift;
kate_state k;
int init;
#ifdef HAVE_TIGER
int use_tiger;
int overlay_dest;
tiger_renderer *tr;
#endif
#endif
} OggPlayKateDecode;
@ -219,11 +234,11 @@ struct _OggPlay {
ogg_int64_t target;
int active_tracks;
volatile OggPlayBuffer * buffer;
ogg_int64_t presentation_time;
ogg_int64_t presentation_time; /**< presentation time in seconds in 32.32 fixed point format */
OggPlaySeekTrash * trash;
int shutdown;
int pt_update_valid;
ogg_int64_t duration; /**< The value of the duration the last time it was retrieved.*/
ogg_int64_t duration; /**< The value of the duration the last time it was retrieved.*/
};
void
@ -244,6 +259,21 @@ typedef struct {
int size;
} OggPlayCallbackFunctions;
/**
* Conversion function for fixed point 32.32 representation of time.
*
* OGGPLAY_TIME_INT_TO_FP(x)
* converts 'x' to a 32.32 fixed point integer
*
* OGGPLAY_TIME_FP_TO_INT
* converts 'x' - a 32.32 fixed point integer - back to normal integer representation
* + changes the order of magnitude by 1000
* e.g. if the fixed point number - 32.32 format - represents seconds
* then the macro will convert it to milliseconds.
*/
#define OGGPLAY_TIME_INT_TO_FP(x) ((x) << 32)
#define OGGPLAY_TIME_FP_TO_INT(x) (((((x) >> 16) * 1000) >> 16) & 0xFFFFFFFF)
/* Allocate and free dynamic memory used by ogg.
* By default they are the ones from stdlib */
#define oggplay_malloc _ogg_malloc

Просмотреть файл

@ -136,6 +136,20 @@ oggplay_seek_cleanup(OggPlay* me, ogg_int64_t milliseconds)
track->stream_info = OGGPLAY_STREAM_JUST_SEEKED;
}
/*
* we need to notify the tiger renderer that we seeked, so that
* now obsolete events are discarded
*/
#ifdef HAVE_TIGER
for (i = 0; i < me->num_tracks; i++) {
OggPlayDecode *track = me->decode_data[i];
if (track && track->content_type == OGGZ_CONTENT_KATE) {
OggPlayKateDecode *decode = (OggPlayKateDecode *)(me->decode_data[i]);
if (decode->use_tiger) tiger_renderer_seek(decode->tr, milliseconds/1000.0);
}
}
#endif
/*
* set the presentation time
*/

Просмотреть файл

@ -38,467 +38,199 @@
* Shane Stephens <shane.stephens@annodex.net>
* Michael Martin
* Marcin Lubonski
* Viktor Gal
*/
#include "oggplay_private.h"
#include "oggplay_yuv2rgb_template.h"
/*
* YUV -> RGB conversion
* R = Y + 1.140V
* G = Y - 0.395U - 0.581V
* B = Y + 2.032U
*
* RGB -> YUV conversion
* Y = 0.299 R + 0.587 G + 0.114 B
* U = 0.147 R - 0.289 G + 0.436 B
* V = 0.615 R - 0.515 G - 0.100 B
/* cpu extension detection */
#include "cpu.c"
/* although we use cpu runtime detection, we still need these
* macros as there's no way e.g. we could compile a x86 asm code
* on a ppc machine and vica-versa
*/
// Optimized YUV to RGB conversion routine disabled due to generating
// incorrect colours. See Annodex trac ticket 421:
// http://trac.annodex.net/ticket/421
#if 0 //defined(__MMX__) || defined(__SSE__) || defined(__SSE2__) || defined(__SSE3__)
#if defined(WIN32)
#define restrict
#include <emmintrin.h>
#else
#include <xmmintrin.h>
#ifndef restrict
#define restrict __restrict__
#endif
#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
#include "oggplay_yuv2rgb_x86.c"
#elif defined(__ppc__) || defined(__ppc64__)
//altivec intristics only working with -maltivec gcc flag,
//but we want runtime altivec detection, hence this has to be
//fixed!
//#include "oggplay_yuv2rgb_altivec.c"
#endif
/* YUV -> RGB Intel MMX implementation */
void oggplay_yuv2rgb(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
static int yuv_initialized;
static ogg_uint32_t cpu_features;
int i;
unsigned char * restrict ptry;
unsigned char * restrict ptru;
unsigned char * restrict ptrv;
unsigned char * ptro;
register __m64 *y, *o;
register __m64 zero, ut, vt, imm, imm2;
register __m64 r, g, b;
register __m64 tmp, tmp2;
zero = _mm_setzero_si64();
ptro = rgb->ptro;
ptry = yuv->ptry;
ptru = yuv->ptru;
ptrv = yuv->ptrv;
for (i = 0; i < yuv->y_height; i++) {
int j;
o = (__m64*)ptro;
ptro += rgb->rgb_width * 4;
for (j = 0; j < yuv->y_width; j += 8) {
y = (__m64*)&ptry[j];
ut = _m_from_int(*(int *)(ptru + j/2));
vt = _m_from_int(*(int *)(ptrv + j/2));
//ut = _m_from_int(0);
//vt = _m_from_int(0);
ut = _m_punpcklbw(ut, zero);
vt = _m_punpcklbw(vt, zero);
/* subtract 128 from u and v */
imm = _mm_set1_pi16(128);
ut = _m_psubw(ut, imm);
vt = _m_psubw(vt, imm);
/* transfer and multiply into r, g, b registers */
imm = _mm_set1_pi16(-51);
g = _m_pmullw(ut, imm);
imm = _mm_set1_pi16(130);
b = _m_pmullw(ut, imm);
imm = _mm_set1_pi16(146);
r = _m_pmullw(vt, imm);
imm = _mm_set1_pi16(-74);
imm = _m_pmullw(vt, imm);
g = _m_paddsw(g, imm);
/* add 64 to r, g and b registers */
imm = _mm_set1_pi16(64);
r = _m_paddsw(r, imm);
g = _m_paddsw(g, imm);
imm = _mm_set1_pi16(32);
b = _m_paddsw(b, imm);
/* shift r, g and b registers to the right */
r = _m_psrawi(r, 7);
g = _m_psrawi(g, 7);
b = _m_psrawi(b, 6);
/* subtract 16 from r, g and b registers */
imm = _mm_set1_pi16(16);
r = _m_psubsw(r, imm);
g = _m_psubsw(g, imm);
b = _m_psubsw(b, imm);
y = (__m64*)&ptry[j];
/* duplicate u and v channels and add y
* each of r,g, b in the form [s1(16), s2(16), s3(16), s4(16)]
* first interleave, so tmp is [s1(16), s1(16), s2(16), s2(16)]
* then add y, then interleave again
* then pack with saturation, to get the desired output of
* [s1(8), s1(8), s2(8), s2(8), s3(8), s3(8), s4(8), s4(8)]
*/
tmp = _m_punpckhwd(r, r);
imm = _m_punpckhbw(*y, zero);
//printf("tmp: %llx imm: %llx\n", tmp, imm);
tmp = _m_paddsw(tmp, imm);
tmp2 = _m_punpcklwd(r, r);
imm2 = _m_punpcklbw(*y, zero);
tmp2 = _m_paddsw(tmp2, imm2);
r = _m_packuswb(tmp2, tmp);
tmp = _m_punpckhwd(g, g);
tmp2 = _m_punpcklwd(g, g);
tmp = _m_paddsw(tmp, imm);
tmp2 = _m_paddsw(tmp2, imm2);
g = _m_packuswb(tmp2, tmp);
tmp = _m_punpckhwd(b, b);
tmp2 = _m_punpcklwd(b, b);
tmp = _m_paddsw(tmp, imm);
tmp2 = _m_paddsw(tmp2, imm2);
b = _m_packuswb(tmp2, tmp);
//printf("duplicated r g and b: %llx %llx %llx\n", r, g, b);
/* now we have 8 8-bit r, g and b samples. we want these to be packed
* into 32-bit values.
*/
//r = _m_from_int(0);
//b = _m_from_int(0);
imm = _mm_set1_pi32(0xFFFFFFFF);
tmp = _m_punpcklbw(r, b);
tmp2 = _m_punpcklbw(g, imm);
*o++ = _m_punpcklbw(tmp, tmp2);
*o++ = _m_punpckhbw(tmp, tmp2);
//printf("tmp, tmp2, write1, write2: %llx %llx %llx %llx\n", tmp, tmp2,
// _m_punpcklbw(tmp, tmp2), _m_punpckhbw(tmp, tmp2));
tmp = _m_punpckhbw(r, b);
tmp2 = _m_punpckhbw(g, imm);
*o++ = _m_punpcklbw(tmp, tmp2);
*o++ = _m_punpckhbw(tmp, tmp2);
//exit(1);
}
if (i & 0x1) {
ptru += yuv->uv_width;
ptrv += yuv->uv_width;
}
ptry += yuv->y_width;
}
_m_empty();
}
/* YUV -> BGR Intel MMX implementation */
void oggplay_yuv2bgr(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
int i;
unsigned char * restrict ptry;
unsigned char * restrict ptru;
unsigned char * restrict ptrv;
unsigned char * ptro;
register __m64 *y, *o;
register __m64 zero, ut, vt, imm, imm2;
register __m64 r, g, b;
register __m64 tmp, tmp2;
zero = _mm_setzero_si64();
ptry = yuv->ptry;
ptru = yuv->ptru;
ptrv = yuv->ptrv;
ptro = rgb->ptro;
for (i = 0; i < yuv->y_height; i++) {
int j;
o = (__m64*)ptro;
ptro += rgb->rgb_width * 4;
for (j = 0; j < yuv->y_width; j += 8) {
y = (__m64*)&ptry[j];
ut = _m_from_int(*(int *)(ptru + j/2));
vt = _m_from_int(*(int *)(ptrv + j/2));
//ut = _m_from_int(0);
//vt = _m_from_int(0);
ut = _m_punpcklbw(ut, zero);
vt = _m_punpcklbw(vt, zero);
/* subtract 128 from u and v */
imm = _mm_set1_pi16(128);
ut = _m_psubw(ut, imm);
vt = _m_psubw(vt, imm);
/* transfer and multiply into r, g, b registers */
imm = _mm_set1_pi16(-51);
g = _m_pmullw(ut, imm);
imm = _mm_set1_pi16(130);
b = _m_pmullw(ut, imm);
imm = _mm_set1_pi16(146);
r = _m_pmullw(vt, imm);
imm = _mm_set1_pi16(-74);
imm = _m_pmullw(vt, imm);
g = _m_paddsw(g, imm);
/* add 64 to r, g and b registers */
imm = _mm_set1_pi16(64);
r = _m_paddsw(r, imm);
g = _m_paddsw(g, imm);
imm = _mm_set1_pi16(32);
b = _m_paddsw(b, imm);
/* shift r, g and b registers to the right */
r = _m_psrawi(r, 7);
g = _m_psrawi(g, 7);
b = _m_psrawi(b, 6);
/* subtract 16 from r, g and b registers */
imm = _mm_set1_pi16(16);
r = _m_psubsw(r, imm);
g = _m_psubsw(g, imm);
b = _m_psubsw(b, imm);
y = (__m64*)&ptry[j];
/* duplicate u and v channels and add y
* each of r,g, b in the form [s1(16), s2(16), s3(16), s4(16)]
* first interleave, so tmp is [s1(16), s1(16), s2(16), s2(16)]
* then add y, then interleave again
* then pack with saturation, to get the desired output of
* [s1(8), s1(8), s2(8), s2(8), s3(8), s3(8), s4(8), s4(8)]
*/
tmp = _m_punpckhwd(r, r);
imm = _m_punpckhbw(*y, zero);
//printf("tmp: %llx imm: %llx\n", tmp, imm);
tmp = _m_paddsw(tmp, imm);
tmp2 = _m_punpcklwd(r, r);
imm2 = _m_punpcklbw(*y, zero);
tmp2 = _m_paddsw(tmp2, imm2);
r = _m_packuswb(tmp2, tmp);
tmp = _m_punpckhwd(g, g);
tmp2 = _m_punpcklwd(g, g);
tmp = _m_paddsw(tmp, imm);
tmp2 = _m_paddsw(tmp2, imm2);
g = _m_packuswb(tmp2, tmp);
tmp = _m_punpckhwd(b, b);
tmp2 = _m_punpcklwd(b, b);
tmp = _m_paddsw(tmp, imm);
tmp2 = _m_paddsw(tmp2, imm2);
b = _m_packuswb(tmp2, tmp);
//printf("duplicated r g and b: %llx %llx %llx\n", r, g, b);
/* now we have 8 8-bit r, g and b samples. we want these to be packed
* into 32-bit values.
*/
//r = _m_from_int(0);
//b = _m_from_int(0);
imm = _mm_set1_pi32(0xFFFFFFFF);
tmp = _m_punpcklbw(b, r);
tmp2 = _m_punpcklbw(g, imm);
*o++ = _m_punpcklbw(tmp, tmp2);
*o++ = _m_punpckhbw(tmp, tmp2);
//printf("tmp, tmp2, write1, write2: %llx %llx %llx %llx\n", tmp, tmp2,
// _m_punpcklbw(tmp, tmp2), _m_punpckhbw(tmp, tmp2));
tmp = _m_punpckhbw(b, r);
tmp2 = _m_punpckhbw(g, imm);
*o++ = _m_punpcklbw(tmp, tmp2);
*o++ = _m_punpckhbw(tmp, tmp2);
//exit(1);
}
if (i & 0x1) {
ptru += yuv->uv_width;
ptrv += yuv->uv_width;
}
ptry += yuv->y_width;
}
_m_empty();
}
#elif defined(__xxAPPLExx__)
/*
* TODO: implement the SIMD method above using Apple's AltiVec code;
* for now, we'll use the vanilla implementation for Macs.
/**
* vanilla implementation of YUV-to-RGB conversion.
*
* - using table-lookups instead of multiplication
* - avoid CLAMPing by incorporating
*
* Also, there's probably a better preprocessor macro for detecting
* the presence of AltiVec than __APPLE__.
*/
/* Macintosh AltiVec implementation */
void oggplay_yuv2rgb(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
}
#else
#define CLAMP(v) ((v) > 255 ? 255 : (v) < 0 ? 0 : (v))
/* Vanilla implementation if YUV->RGB conversion */
void oggplay_yuv2rgb(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
#define prec 15
static const int CoY = (int)(1.164 * (1 << prec) + 0.5);
static const int CoRV = (int)(1.596 * (1 << prec) + 0.5);
static const int CoGU = (int)(0.391 * (1 << prec) + 0.5);
static const int CoGV = (int)(0.813 * (1 << prec) + 0.5);
static const int CoBU = (int)(2.018 * (1 << prec) + 0.5);
unsigned char * ptry = yuv->ptry;
unsigned char * ptru = yuv->ptru;
unsigned char * ptrv = yuv->ptrv;
unsigned char * ptro = rgb->ptro;
unsigned char * ptro2;
int i, j;
static int CoefsGU[256];
static int CoefsGV[256];
static int CoefsBU[256];
static int CoefsRV[256];
static int CoefsY[256];
for (i = 0; i < yuv->y_height; i++) {
ptro2 = ptro;
for (j = 0; j < yuv->y_width; j += 2) {
/**
* Initialize the lookup-table for vanilla yuv to rgb conversion
* and the cpu_features global.
*/
static void
init_yuv_converters()
{
int i;
short pr, pg, pb, y;
short r, g, b;
for(i = 0; i < 256; ++i)
{
CoefsGU[i] = -CoGU * (i - 128);
CoefsGV[i] = -CoGV * (i - 128);
CoefsBU[i] = CoBU * (i - 128);
CoefsRV[i] = CoRV * (i - 128);
CoefsY[i] = CoY * (i - 16) + (prec/2);
}
pr = (-56992 + ptrv[j/2] * 409) >> 8;
pg = (34784 - ptru[j/2] * 100 - ptrv[j/2] * 208) >> 8;
pb = (-70688 + ptru[j/2] * 516) >> 8;
y = 298*ptry[j] >> 8;
r = y + pr;
g = y + pg;
b = y + pb;
*ptro2++ = CLAMP(r);
*ptro2++ = CLAMP(g);
*ptro2++ = CLAMP(b);
*ptro2++ = 255;
y = 298*ptry[j + 1] >> 8;
r = y + pr;
g = y + pg;
b = y + pb;
*ptro2++ = CLAMP(r);
*ptro2++ = CLAMP(g);
*ptro2++ = CLAMP(b);
*ptro2++ = 255;
}
ptry += yuv->y_width;
if (i & 1) {
ptru += yuv->uv_width;
ptrv += yuv->uv_width;
}
ptro += rgb->rgb_width * 4;
}
cpu_features = oc_cpu_flags_get();
yuv_initialized = 1;
}
/* Vanilla implementation if YUV->ARGB conversion */
void oggplay_yuv2argb(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
#define VANILLA_YUV2RGB_PIXEL(y, ruv, guv, buv) \
r = (CoefsY[y] + ruv) >> prec; \
g = (CoefsY[y] + guv) >> prec; \
b = (CoefsY[y] + buv) >> prec; \
unsigned char * ptry = yuv->ptry;
unsigned char * ptru = yuv->ptru;
unsigned char * ptrv = yuv->ptrv;
unsigned char * ptro = rgb->ptro;
unsigned char * ptro2;
int i, j;
#define VANILLA_RGBA_OUT(out, r, g, b) \
out[0] = CLAMP(r); \
out[1] = CLAMP(g); \
out[2] = CLAMP(b); \
out[3] = 255;
for (i = 0; i < yuv->y_height; i++) {
ptro2 = ptro;
for (j = 0; j < yuv->y_width; j += 2) {
#define VANILLA_BGRA_OUT(out, r, g, b) \
out[0] = CLAMP(b); \
out[1] = CLAMP(g); \
out[2] = CLAMP(r); \
out[3] = 255;
short pr, pg, pb, y;
short r, g, b;
#define VANILLA_ARGB_OUT(out, r, g, b) \
out[0] = 255; \
out[1] = CLAMP(r); \
out[2] = CLAMP(g); \
out[3] = CLAMP(b);
pr = (-56992 + ptrv[j/2] * 409) >> 8;
pg = (34784 - ptru[j/2] * 100 - ptrv[j/2] * 208) >> 8;
pb = (-70688 + ptru[j/2] * 516) >> 8;
#define VANILLA_ABGR_OUT(out, r, g, b) \
out[0] = 255; \
out[1] = CLAMP(b); \
out[2] = CLAMP(g); \
out[3] = CLAMP(r);
y = 298*ptry[j] >> 8;
r = y + pr;
g = y + pg;
b = y + pb;
/* yuv420p -> */
#define LOOKUP_COEFFS int ruv = CoefsRV[*pv]; \
int guv = CoefsGU[*pu] + CoefsGV[*pv]; \
int buv = CoefsBU[*pu]; \
int r, g, b;
*ptro2++ = 255;
*ptro2++ = CLAMP(r);
*ptro2++ = CLAMP(g);
*ptro2++ = CLAMP(b);
#define CONVERT(OUTPUT_FUNC) LOOKUP_COEFFS \
VANILLA_YUV2RGB_PIXEL(py[0], ruv, guv, buv);\
OUTPUT_FUNC(dst, r, g, b); \
VANILLA_YUV2RGB_PIXEL(py[1], ruv, guv, buv);\
OUTPUT_FUNC((dst+4), r, g, b);
y = 298*ptry[j + 1] >> 8;
r = y + pr;
g = y + pg;
b = y + pb;
#define CLEANUP
*ptro2++ = 255;
*ptro2++ = CLAMP(r);
*ptro2++ = CLAMP(g);
*ptro2++ = CLAMP(b);
}
ptry += yuv->y_width;
if (i & 1) {
ptru += yuv->uv_width;
ptrv += yuv->uv_width;
}
ptro += rgb->rgb_width * 4;
}
}
YUV_CONVERT(yuv420_to_rgba_vanilla, CONVERT(VANILLA_RGBA_OUT), 2, 8, 2, 1)
YUV_CONVERT(yuv420_to_bgra_vanilla, CONVERT(VANILLA_BGRA_OUT), 2, 8, 2, 1)
YUV_CONVERT(yuv420_to_abgr_vanilla, CONVERT(VANILLA_ABGR_OUT), 2, 8, 2, 1)
YUV_CONVERT(yuv420_to_argb_vanilla, CONVERT(VANILLA_ARGB_OUT), 2, 8, 2, 1)
#undef CONVERT
#undef CLEANUP
/* Vanilla implementation of YUV->BGR conversion*/
void oggplay_yuv2bgr(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
unsigned char * ptry = yuv->ptry;
unsigned char * ptru = yuv->ptru;
unsigned char * ptrv = yuv->ptrv;
unsigned char * ptro = rgb->ptro;
unsigned char * ptro2;
int i, j;
for (i = 0; i < yuv->y_height; i++) {
ptro2 = ptro;
for (j = 0; j < yuv->y_width; j += 2) {
short pr, pg, pb, y;
short r, g, b;
pr = (-56992 + ptrv[j/2] * 409) >> 8;
pg = (34784 - ptru[j/2] * 100 - ptrv[j/2] * 208) >> 8;
pb = (-70688 + ptru[j/2] * 516) >> 8;
y = 298*ptry[j] >> 8;
r = y + pr;
g = y + pg;
b = y + pb;
*ptro2++ = CLAMP(b);
*ptro2++ = CLAMP(g);
*ptro2++ = CLAMP(r);
*ptro2++ = 255;
y = 298*ptry[j + 1] >> 8;
r = y + pr;
g = y + pg;
b = y + pb;
*ptro2++ = CLAMP(b);
*ptro2++ = CLAMP(g);
*ptro2++ = CLAMP(r);
*ptro2++ = 255;
}
ptry += yuv->y_width;
if (i & 1) {
ptru += yuv->uv_width;
ptrv += yuv->uv_width;
}
ptro += rgb->rgb_width * 4;
}
}
void
oggplay_yuv2rgba(const OggPlayYUVChannels* yuv, OggPlayRGBChannels* rgb)
{
if (!yuv_initialized)
init_yuv_converters();
#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
if (yuv->y_width % 16 == 0 && cpu_features & OC_CPU_X86_SSE2)
return yuv420_to_rgba_sse2(yuv, rgb);
#endif
if (yuv->y_width % 8 == 0 && cpu_features & OC_CPU_X86_MMX)
return yuv420_to_rgba_mmx(yuv, rgb);
#elif defined(__ppc__) || defined(__ppc64__)
if (yuv->y_width % 16 == 0 && yuv->y_height % 2 == 0 && cpu_features & OC_CPU_PPC_ALTIVEC)
return yuv420_to_abgr_vanilla(yuv, rgb);
#endif
#if WORDS_BIGENDIAN || IS_BIG_ENDIAN
return yuv420_to_abgr_vanilla(yuv, rgb);
#else
return yuv420_to_rgba_vanilla(yuv, rgb);
#endif
}
void
oggplay_yuv2bgra(const OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb)
{
if (!yuv_initialized)
init_yuv_converters();
#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
if (yuv->y_width % 16 == 0 && cpu_features & OC_CPU_X86_SSE2)
return yuv420_to_bgra_sse2(yuv, rgb);
#endif
if (yuv->y_width % 8 == 0 && cpu_features & OC_CPU_X86_MMX)
return yuv420_to_bgra_mmx(yuv, rgb);
#elif defined(__ppc__) || defined(__ppc64__)
if (yuv->y_width % 16 == 0 && yuv->y_height % 2 == 0 && cpu_features & OC_CPU_PPC_ALTIVEC)
return yuv420_to_argb_vanilla(yuv, rgb);
#endif
#if WORDS_BIGENDIAN || IS_BIG_ENDIAN
return yuv420_to_argb_vanilla(yuv, rgb);
#else
return yuv420_to_bgra_vanilla(yuv, rgb);
#endif
}
void
oggplay_yuv2argb(const OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb)
{
if (!yuv_initialized)
init_yuv_converters();
#if defined(i386) || defined(__x86__) || defined(__x86_64__) || defined(_M_IX86)
#if defined(_MSC_VER) || (defined(ATTRIBUTE_ALIGNED_MAX) && ATTRIBUTE_ALIGNED_MAX >= 16)
if (yuv->y_width % 16 == 0 && cpu_features & OC_CPU_X86_SSE2)
return yuv420_to_argb_sse2(yuv, rgb);
#endif
if (yuv->y_width % 8 == 0 && cpu_features & OC_CPU_X86_MMX)
return yuv420_to_argb_mmx(yuv, rgb);
#elif defined(__ppc__) || defined(__ppc64__)
if (yuv->y_width % 16 == 0 && yuv->y_height % 2 == 0 && cpu_features & OC_CPU_PPC_ALTIVEC)
return yuv420_to_bgra_vanilla(yuv, rgb);
#endif
#if WORDS_BIGENDIAN || IS_BIG_ENDIAN
return yuv420_to_bgra_vanilla(yuv, rgb);
#else
return yuv420_to_argb_vanilla(yuv, rgb);
#endif
}

Просмотреть файл

@ -0,0 +1,68 @@
#ifndef __OGGPLAY_YUV2RGB_TEMPLATE_H__
#define __OGGPLAY_YUV2RGB_TEMPLATE_H__
#if defined(WIN32)
#define restrict
#else
#ifndef restrict
#define restrict __restrict__
#endif
#endif
/**
* Template for YUV to RGB conversion
*
* @param FUNC function name
* @param CONVERT a macro that defines
* @param NUM_PIXELS number of pixels processed in one iteration
* @param OUT_SHIFT number of pixels to shift after one iteration in rgb data stream
* @param Y_SHIFT number of pixels to shift after one iteration in Y data stream
* @param UV_SHIFT
*/
#define YUV_CONVERT(FUNC, CONVERT, NUM_PIXELS, OUT_SHIFT, Y_SHIFT, UV_SHIFT)\
static void \
(FUNC)(const OggPlayYUVChannels* yuv, OggPlayRGBChannels* rgb) \
{ \
int i,j, w, h; \
unsigned char* restrict ptry; \
unsigned char* restrict ptru; \
unsigned char* restrict ptrv; \
unsigned char* restrict ptro; \
unsigned char *dst, *py, *pu, *pv; \
\
ptro = rgb->ptro; \
ptry = yuv->ptry; \
ptru = yuv->ptru; \
ptrv = yuv->ptrv; \
\
w = yuv->y_width/NUM_PIXELS; \
h = yuv->y_height; \
for (i = 0; i < h; ++i) \
{ \
py = ptry; \
pu = ptru; \
pv = ptrv; \
dst = ptro; \
for (j = 0; j < w; ++j, \
dst += OUT_SHIFT, \
py += Y_SHIFT, \
pu += UV_SHIFT, \
pv += UV_SHIFT) \
{ \
/* use the given conversion function */ \
CONVERT \
} \
ptro += rgb->rgb_width * 4; \
ptry += yuv->y_width; \
\
if (i & 0x1) \
{ \
ptru += yuv->uv_width; \
ptrv += yuv->uv_width; \
} \
} \
CLEANUP \
}
#endif

Просмотреть файл

@ -0,0 +1,136 @@
/*
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
Organisation (CSIRO) Australia
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of CSIRO Australia nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* YUV to RGB conversion using x86 CPU extensions
*/
#if defined(_MSC_VER)
#include "yuv2rgb_x86_vs.h"
#elif defined(__GNUC__)
#include "yuv2rgb_x86.h"
#endif
typedef union
{
long long q[2];
unsigned long long uq[2];
int d[4];
unsigned int ud[4];
short w[8];
unsigned short uw[8];
char b[16];
unsigned char ub[16];
float s[4];
} ATTR_ALIGN(16) simd_t;
#define UV_128 0x0080008000800080LL
#define Y_16 0x1010101010101010LL
#define Y_Co 0x253f253f253f253fLL
#define GU_Co 0xf37df37df37df37dLL
#define GV_Co 0xe5fce5fce5fce5fcLL
#define BU_Co 0x4093409340934093LL
#define RV_Co 0x3312331233123312LL
#define Y_MASK 0x00ff00ff00ff00ffLL
#define ALFA 0xffffffffffffffffLL
/**
* coefficients and constants for yuv to rgb SIMD conversion
*/
static const simd_t simd_table[9] = {
{{UV_128, UV_128}},
{{GU_Co, GU_Co}},
{{GV_Co, GV_Co}},
{{BU_Co, BU_Co}},
{{RV_Co, RV_Co}},
{{Y_16, Y_16}},
{{Y_Co, Y_Co}},
{{Y_MASK, Y_MASK}},
{{ALFA, ALFA}}
};
/**
* the conversion functions using MMX instructions
*/
/* template for the MMX conversion functions */
#define YUV_CONVERT_MMX(FUNC, CONVERT) YUV_CONVERT(FUNC, CONVERT, 8, 32, 8, 4)
#define CLEANUP emms()
#define OUT_RGBA_32 OUTPUT_RGBA_32(movq, mm, 8, 16, 24)
#define OUT_ARGB_32 OUTPUT_ARGB_32(movq, mm, 8, 16, 24)
#define OUT_BGRA_32 OUTPUT_BGRA_32(movq, mm, 8, 16, 24)
#define MOVNTQ MMX_MOVNTQ
/* yuv420 -> */
#define CONVERT(OUTPUT_FUNC) LOAD_YUV_PLANAR_2(movq, mm) \
YUV_2_RGB(movq, mm) \
OUTPUT_FUNC
YUV_CONVERT_MMX(yuv420_to_rgba_mmx, CONVERT(OUT_RGBA_32))
YUV_CONVERT_MMX(yuv420_to_bgra_mmx, CONVERT(OUT_BGRA_32))
YUV_CONVERT_MMX(yuv420_to_argb_mmx, CONVERT(OUT_ARGB_32))
#undef CONVERT
#undef CLEANUP
#undef OUT_RGBA_32
#undef OUT_ARGB_32
#undef OUT_BGRA_32
#undef MOVNTQ
/**
* the conversion functions using SSE2 instructions
*/
/* template for the SSE2 conversion functions */
#define YUV_CONVERT_SSE2(FUNC, CONVERT) YUV_CONVERT(FUNC, CONVERT, 16, 64, 16, 8)
#define OUT_RGBA_32 OUTPUT_RGBA_32(movdqa, xmm, 16, 32, 48)
#define OUT_ARGB_32 OUTPUT_ARGB_32(movdqa, xmm, 16, 32, 48)
#define OUT_BGRA_32 OUTPUT_BGRA_32(movdqa, xmm, 16, 32, 48)
#define MOVNTQ SSE2_MOVNTQ
#define CLEANUP
/* yuv420 -> */
#define CONVERT(OUTPUT_FUNC) LOAD_YUV_PLANAR_2(movdqu, xmm) \
YUV_2_RGB(movdqa, xmm) \
OUTPUT_FUNC
YUV_CONVERT_SSE2(yuv420_to_rgba_sse2, CONVERT(OUT_RGBA_32))
YUV_CONVERT_SSE2(yuv420_to_bgra_sse2, CONVERT(OUT_BGRA_32))
YUV_CONVERT_SSE2(yuv420_to_argb_sse2, CONVERT(OUT_ARGB_32))
#undef CONVERT
#undef OUT_RGBA_32
#undef OUT_ARGB_32
#undef OUT_BGRA_32
#undef MOVNTQ
#undef CLEANUP

Просмотреть файл

@ -89,7 +89,7 @@ typedef sem_t semaphore;
#define SEM_CLOSE(p) (!CloseHandle(p))
typedef HANDLE semaphore;
#elif defined(__APPLE__)
#include <Multiprocessing.h>
#include <Carbon/Carbon.h>
#define SEM_CREATE(p,s) MPCreateSemaphore(s, s, &(p))
#define SEM_SIGNAL(p) MPSignalSemaphore(p)
#define SEM_WAIT(p) MPWaitOnSemaphore(p, kDurationForever)

Просмотреть файл

@ -0,0 +1,134 @@
#ifndef __YUV2RGB_X86_H__
#define __YUV2RGB_X86_H__
# ifdef ATTRIBUTE_ALIGNED_MAX
#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
# else
#define ATTR_ALIGN(align)
# endif
#define emms() __asm__ __volatile__ ( "emms;" );
#define MMX_MOVNTQ "movntq"
#define SSE2_MOVNTQ "movdqu"
#define YUV_2_RGB(mov_instr, reg_type) \
__asm__ __volatile__ ( \
"punpcklbw %%"#reg_type"4, %%"#reg_type"0;" /* mm0 = u3 u2 u1 u0 */\
"punpcklbw %%"#reg_type"4, %%"#reg_type"1;" /* mm1 = v3 v2 v1 v0 */\
"psubsw (%0), %%"#reg_type"0;" /* u -= 128 */\
"psubsw (%0), %%"#reg_type"1;" /* v -= 128 */\
"psllw $3, %%"#reg_type"0;" /* promote precision */\
"psllw $3, %%"#reg_type"1;" /* promote precision */\
#mov_instr " %%"#reg_type"0, %%"#reg_type"2;" /* mm2 = u3 u2 u1 u0 */\
#mov_instr " %%"#reg_type"1, %%"#reg_type"3;" /* mm3 = v3 v2 v1 v0 */\
"pmulhw 16(%0), %%"#reg_type"2;" /* mm2 = u * u_green */\
"pmulhw 32(%0), %%"#reg_type"3;" /* mm3 = v * v_green */\
"pmulhw 48(%0), %%"#reg_type"0;" /* mm0 = chroma_b */\
"pmulhw 64(%0), %%"#reg_type"1;" /* mm1 = chroma_r */\
"paddsw %%"#reg_type"3, %%"#reg_type"2;" /* mm2 = chroma_g */\
"psubusb 80(%0), %%"#reg_type"6;" /* Y -= 16 */\
#mov_instr " %%"#reg_type"6, %%"#reg_type"7;" /* mm7 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */\
"pand 112(%0), %%"#reg_type"6;" /* mm6 = Y6 Y4 Y2 Y0 */\
"psrlw $8, %%"#reg_type"7;" /* mm7 = Y7 Y5 Y3 Y1 */\
"psllw $3, %%"#reg_type"6;" /* promote precision */\
"psllw $3, %%"#reg_type"7;" /* promote precision */\
"pmulhw 96(%0), %%"#reg_type"6;" /* mm6 = luma_rgb even */\
"pmulhw 96(%0), %%"#reg_type"7;" /* mm7 = luma_rgb odd */\
#mov_instr " %%"#reg_type"0, %%"#reg_type"3;" /* mm3 = chroma_b */\
#mov_instr " %%"#reg_type"1, %%"#reg_type"4;" /* mm4 = chroma_r */\
#mov_instr " %%"#reg_type"2, %%"#reg_type"5;" /* mm5 = chroma_g */\
"paddsw %%"#reg_type"6, %%"#reg_type"0;" /* mm0 = B6 B4 B2 B0 */\
"paddsw %%"#reg_type"7, %%"#reg_type"3;" /* mm3 = B7 B5 B3 B1 */\
"paddsw %%"#reg_type"6, %%"#reg_type"1;" /* mm1 = R6 R4 R2 R0 */\
"paddsw %%"#reg_type"7, %%"#reg_type"4;" /* mm4 = R7 R5 R3 R1 */\
"paddsw %%"#reg_type"6, %%"#reg_type"2;" /* mm2 = G6 G4 G2 G0 */\
"paddsw %%"#reg_type"7, %%"#reg_type"5;" /* mm5 = G7 G5 G3 G1 */\
"packuswb %%"#reg_type"0, %%"#reg_type"0;" /* saturate to 0-255 */\
"packuswb %%"#reg_type"1, %%"#reg_type"1;" /* saturate to 0-255 */\
"packuswb %%"#reg_type"2, %%"#reg_type"2;" /* saturate to 0-255 */\
"packuswb %%"#reg_type"3, %%"#reg_type"3;" /* saturate to 0-255 */\
"packuswb %%"#reg_type"4, %%"#reg_type"4;" /* saturate to 0-255 */\
"packuswb %%"#reg_type"5, %%"#reg_type"5;" /* saturate to 0-255 */\
"punpcklbw %%"#reg_type"3, %%"#reg_type"0;" /* mm0 = B7 B6 B5 B4 B3 B2 B1 B0 */\
"punpcklbw %%"#reg_type"4, %%"#reg_type"1;" /* mm1 = R7 R6 R5 R4 R3 R2 R1 R0 */\
"punpcklbw %%"#reg_type"5, %%"#reg_type"2;" /* mm2 = G7 G6 G5 G4 G3 G2 G1 G0 */\
::"r" (simd_table));
#define OUTPUT_BGRA_32(mov_instr, reg_type, offset0, offset1, offset2) \
__asm__ __volatile__ ( \
/* r0=B, r1=R, r2=G */ \
#mov_instr " 128(%1), %%"#reg_type"3;\n\t"\
#mov_instr " %%"#reg_type"0, %%"#reg_type"4;\n\t"\
#mov_instr " %%"#reg_type"1, %%"#reg_type"5;\n\t"\
"punpcklbw %%"#reg_type"2, %%"#reg_type"0;\n\t" /* GB GB GB GB low */\
"punpcklbw %%"#reg_type"3, %%"#reg_type"1;\n\t" /* FR FR FR FR low */\
"punpckhbw %%"#reg_type"2, %%"#reg_type"4;\n\t" /* GB GB GB GB high */\
"punpckhbw %%"#reg_type"3, %%"#reg_type"5;\n\t" /* FR FR FR FR high */\
#mov_instr " %%"#reg_type"0, %%"#reg_type"6;\n\t"\
#mov_instr " %%"#reg_type"4, %%"#reg_type"7;\n\t"\
"punpcklwd %%"#reg_type"1, %%"#reg_type"0;\n\t" /* FRGB FRGB 0 */\
"punpckhwd %%"#reg_type"1, %%"#reg_type"6;\n\t" /* FRGB FRGB 1 */\
"punpcklwd %%"#reg_type"5, %%"#reg_type"4;\n\t" /* FRGB FRGB 2 */\
"punpckhwd %%"#reg_type"5, %%"#reg_type"7;\n\t" /* FRGB FRGB 3 */\
MOVNTQ " %%"#reg_type"0, (%0);\n\t"\
MOVNTQ " %%"#reg_type"6, "#offset0"(%0);\n\t"\
MOVNTQ " %%"#reg_type"4, "#offset1"(%0);\n\t"\
MOVNTQ " %%"#reg_type"7, "#offset2"(%0);\n\t"\
:: "r" (dst), "r" (simd_table));
#define OUTPUT_ARGB_32(mov_instr, reg_type, offset0, offset1, offset2) \
__asm__ __volatile__ ( \
/* r0=B, r1=R, r2=G */ \
#mov_instr " 128(%1), %%"#reg_type"3;\n\t"\
#mov_instr " %%"#reg_type"3, %%"#reg_type"4;\n\t"\
#mov_instr " %%"#reg_type"2, %%"#reg_type"5;\n\t"\
"punpcklbw %%"#reg_type"0, %%"#reg_type"2;\n\t" /* BG BG BG BG low */\
"punpcklbw %%"#reg_type"1, %%"#reg_type"3;\n\t" /* RF RF RF RF low */\
"punpckhbw %%"#reg_type"0, %%"#reg_type"5;\n\t" /* BG BG BG BG high */\
"punpckhbw %%"#reg_type"1, %%"#reg_type"4;\n\t" /* RF RF RF RF high */\
#mov_instr " %%"#reg_type"3, %%"#reg_type"0;\n\t"\
#mov_instr " %%"#reg_type"4, %%"#reg_type"1;\n\t"\
"punpcklwd %%"#reg_type"2, %%"#reg_type"3;\n\t" /* BGRF BGRF 0 */\
"punpckhwd %%"#reg_type"2, %%"#reg_type"0;\n\t" /* BGRF BGRF 1 */\
"punpcklwd %%"#reg_type"5, %%"#reg_type"4;\n\t" /* BGRF BGRF 2 */\
"punpckhwd %%"#reg_type"5, %%"#reg_type"1;\n\t" /* BGRF BGRF 3 */\
MOVNTQ " %%"#reg_type"3, (%0);\n\t"\
MOVNTQ " %%"#reg_type"0, "#offset0"(%0);\n\t"\
MOVNTQ " %%"#reg_type"4, "#offset1"(%0);\n\t"\
MOVNTQ " %%"#reg_type"1, "#offset2"(%0);\n\t"\
:: "r" (dst), "r" (simd_table));
#define OUTPUT_RGBA_32(mov_instr, reg_type, offset0, offset1, offset2) \
__asm__ __volatile__ ( \
/* r0=B, r1=R, r2=G */ \
#mov_instr " 128(%1), %%"#reg_type"3;\n\t"\
#mov_instr " %%"#reg_type"1, %%"#reg_type"4;\n\t"\
#mov_instr " %%"#reg_type"0, %%"#reg_type"5;\n\t"\
"punpcklbw %%"#reg_type"2, %%"#reg_type"1;\n\t" /* GR GR GR GR low */\
"punpcklbw %%"#reg_type"3, %%"#reg_type"0;\n\t" /* 0B 0B 0B 0B low */\
"punpckhbw %%"#reg_type"2, %%"#reg_type"4;\n\t" /* GR GR GR GR high */\
"punpckhbw %%"#reg_type"3, %%"#reg_type"5;\n\t" /* 0B 0B 0B 0B high */\
#mov_instr " %%"#reg_type"1, %%"#reg_type"6;\n\t"\
#mov_instr " %%"#reg_type"4, %%"#reg_type"7;\n\t"\
"punpcklwd %%"#reg_type"0, %%"#reg_type"1;\n\t" /* 0BGR 0BGR 0 */\
"punpckhwd %%"#reg_type"0, %%"#reg_type"6;\n\t" /* 0BGR 0BGR 1 */\
"punpcklwd %%"#reg_type"5, %%"#reg_type"4;\n\t" /* 0BGR 0BGR 2 */\
"punpckhwd %%"#reg_type"5, %%"#reg_type"7;\n\t" /* 0BGR 0BGR 3 */\
MOVNTQ " %%"#reg_type"1, (%0);\n\t"\
MOVNTQ " %%"#reg_type"6, "#offset0"(%0);\n\t"\
MOVNTQ " %%"#reg_type"4, "#offset1"(%0);\n\t"\
MOVNTQ " %%"#reg_type"7, "#offset2"(%0);\n\t"\
:: "r" (dst), "r" (simd_table));
#define LOAD_YUV_PLANAR_2(mov_instr, reg_type) \
__asm__ __volatile__ ( \
#mov_instr " %0, %%"#reg_type"6;\n\t" \
#mov_instr " %1, %%"#reg_type"0;\n\t" \
#mov_instr " %2, %%"#reg_type"1;\n\t" \
"pxor %%"#reg_type"4, %%"#reg_type"4;\n\t" \
:: "m" (*py), "m" (*pu), "m" (*pv));
#endif /* __YUV2RGB_X86_H__ */

Просмотреть файл

@ -0,0 +1,131 @@
#ifndef __OGGPLAY_YUV2RGB_VS_H__
#define __OGGPLAY_YUV2RGB_VS_H__
#define ATTR_ALIGN(_align) __declspec(align(_align))
#define emms() __asm emms
#define MMX_MOVNTQ movntq
#define SSE2_MOVNTQ movdqu
#define LOAD_YUV_PLANAR_2(mov_instr, reg_type) \
__asm { \
__asm mov eax, py \
__asm mov edx, pu \
__asm mov_instr reg_type##6, [eax] \
__asm mov_instr reg_type##0, [edx] \
__asm mov eax, pv \
__asm mov_instr reg_type##1, [eax] \
__asm pxor reg_type##4, reg_type##4 \
}
#define OUTPUT_RGBA_32(mov_instr, reg_type, offset0, offset1, offset2) \
__asm { \
__asm mov eax, dst \
__asm mov_instr reg_type##3, [simd_table+128] \
__asm mov_instr reg_type##4, reg_type##1 \
__asm mov_instr reg_type##5, reg_type##0 \
__asm punpcklbw reg_type##1, reg_type##2 \
__asm punpcklbw reg_type##0, reg_type##3 \
__asm punpckhbw reg_type##4, reg_type##2 \
__asm punpckhbw reg_type##5, reg_type##3 \
__asm mov_instr reg_type##6, reg_type##1 \
__asm mov_instr reg_type##7, reg_type##4 \
__asm punpcklwd reg_type##1, reg_type##0 \
__asm punpckhwd reg_type##6, reg_type##0 \
__asm punpcklwd reg_type##4, reg_type##5 \
__asm punpckhwd reg_type##7, reg_type##5 \
__asm MOVNTQ [eax], reg_type##1 \
__asm MOVNTQ [eax+offset0], reg_type##6 \
__asm MOVNTQ [eax+offset1], reg_type##4 \
__asm MOVNTQ [eax+offset2], reg_type##7 \
}
#define OUTPUT_ARGB_32(mov_instr, reg_type, offset0, offset1, offset2) \
__asm { \
__asm mov eax, dst \
__asm mov_instr reg_type##3, [simd_table+128] \
__asm mov_instr reg_type##4, reg_type##3 \
__asm mov_instr reg_type##5, reg_type##2 \
__asm punpcklbw reg_type##2, reg_type##0 \
__asm punpcklbw reg_type##3, reg_type##1 \
__asm punpckhbw reg_type##5, reg_type##0 \
__asm punpckhbw reg_type##4, reg_type##1 \
__asm mov_instr reg_type##0, reg_type##3 \
__asm mov_instr reg_type##1, reg_type##4 \
__asm punpcklwd reg_type##3, reg_type##2 \
__asm punpckhwd reg_type##0, reg_type##2 \
__asm punpcklwd reg_type##4, reg_type##5 \
__asm punpckhwd reg_type##1, reg_type##5 \
__asm MOVNTQ [eax], reg_type##3 \
__asm MOVNTQ [eax+offset0], reg_type##0 \
__asm MOVNTQ [eax+offset1], reg_type##4 \
__asm MOVNTQ [eax+offset2], reg_type##1 \
}
#define OUTPUT_BGRA_32(mov_instr, reg_type, offset0, offset1, offset2) \
__asm { \
__asm mov eax, dst \
__asm mov_instr reg_type##3, [simd_table+128] \
__asm mov_instr reg_type##4, reg_type##0 \
__asm mov_instr reg_type##5, reg_type##1 \
__asm punpcklbw reg_type##0, reg_type##2 \
__asm punpcklbw reg_type##1, reg_type##3 \
__asm punpckhbw reg_type##4, reg_type##2 \
__asm punpckhbw reg_type##5, reg_type##3 \
__asm mov_instr reg_type##6, reg_type##0 \
__asm mov_instr reg_type##7, reg_type##4 \
__asm punpcklwd reg_type##0, reg_type##1 \
__asm punpckhwd reg_type##6, reg_type##1 \
__asm punpcklwd reg_type##4, reg_type##5 \
__asm punpckhwd reg_type##7, reg_type##5 \
__asm MOVNTQ [eax], reg_type##0 \
__asm MOVNTQ [eax+offset0], reg_type##6 \
__asm MOVNTQ [eax+offset1], reg_type##4 \
__asm MOVNTQ [eax+offset2], reg_type##7 \
}
#define YUV_2_RGB(mov_instr, reg_type) \
__asm { \
__asm punpcklbw reg_type##0, reg_type##4 /* mm0 = u3 u2 u1 u0 */\
__asm punpcklbw reg_type##1, reg_type##4 /* mm1 = v3 v2 v1 v0 */\
__asm psubsw reg_type##0, [simd_table] /* u -= 128 */\
__asm psubsw reg_type##1, [simd_table] /* v -= 128 */\
__asm psllw reg_type##0, 3 /* promote precision */\
__asm psllw reg_type##1, 3 /* promote precision */\
__asm mov_instr reg_type##2, reg_type##0 /* mm2 = u3 u2 u1 u0 */\
__asm mov_instr reg_type##3, reg_type##1 /* mm3 = v3 v2 v1 v0 */\
__asm pmulhw reg_type##2, [simd_table+16] /* mm2 = u * u_green */\
__asm pmulhw reg_type##3, [simd_table+32] /* mm3 = v * v_green */\
__asm pmulhw reg_type##0, [simd_table+48] /* mm0 = chroma_b */\
__asm pmulhw reg_type##1, [simd_table+64] /* mm1 = chroma_r */\
__asm paddsw reg_type##2, reg_type##3 /* mm2 = chroma_g */\
__asm psubusb reg_type##6, [simd_table+80] /* Y -= 16 */\
__asm mov_instr reg_type##7, reg_type##6 /* mm7 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */\
__asm pand reg_type##6, [simd_table+112] /* mm6 = Y6 Y4 Y2 Y0 */\
__asm psrlw reg_type##7, 8 /* mm7 = Y7 Y5 Y3 Y1 */\
__asm psllw reg_type##6, 3 /* promote precision */\
__asm psllw reg_type##7, 3 /* promote precision */\
__asm pmulhw reg_type##6, [simd_table+96] /* mm6 = luma_rgb even */\
__asm pmulhw reg_type##7, [simd_table+96] /* mm7 = luma_rgb odd */\
__asm mov_instr reg_type##3, reg_type##0 /* mm3 = chroma_b */\
__asm mov_instr reg_type##4, reg_type##1 /* mm4 = chroma_r */\
__asm mov_instr reg_type##5, reg_type##2 /* mm5 = chroma_g */\
__asm paddsw reg_type##0, reg_type##6 /* mm0 = B6 B4 B2 B0 */\
__asm paddsw reg_type##3, reg_type##7 /* mm3 = B7 B5 B3 B1 */\
__asm paddsw reg_type##1, reg_type##6 /* mm1 = R6 R4 R2 R0 */\
__asm paddsw reg_type##4, reg_type##7 /* mm4 = R7 R5 R3 R1 */\
__asm paddsw reg_type##2, reg_type##6 /* mm2 = G6 G4 G2 G0 */\
__asm paddsw reg_type##5, reg_type##7 /* mm5 = G7 G5 G3 G1 */\
__asm packuswb reg_type##0, reg_type##0 /* saturate to 0-255 */\
__asm packuswb reg_type##1, reg_type##1 /* saturate to 0-255 */\
__asm packuswb reg_type##2, reg_type##2 /* saturate to 0-255 */\
__asm packuswb reg_type##3, reg_type##3 /* saturate to 0-255 */\
__asm packuswb reg_type##4, reg_type##4 /* saturate to 0-255 */\
__asm packuswb reg_type##5, reg_type##5 /* saturate to 0-255 */\
__asm punpcklbw reg_type##0, reg_type##3 /* mm0 = B7 B6 B5 B4 B3 B2 B1 B0 */\
__asm punpcklbw reg_type##1, reg_type##4 /* mm1 = R7 R6 R5 R4 R3 R2 R1 R0 */\
__asm punpcklbw reg_type##2, reg_type##5 /* mm2 = G7 G6 G5 G4 G3 G2 G1 G0 */\
}
#endif

Просмотреть файл

@ -2,7 +2,7 @@
#
# Copies the needed files from a directory containing the original
# liboggplay source that we need for the Mozilla HTML5 media support.
sed s/\#define\ __SSE2__\ 1//g $1/config.h >./src/liboggplay/config.h
sed 's/#define ATTRIBUTE_ALIGNED_MAX .*//g' $1/config.h >./src/liboggplay/config.h
echo "#undef HAVE_GLUT" >>./src/liboggplay/config.h
cp $1/include/oggplay/oggplay_callback_info.h ./include/oggplay/oggplay_callback_info.h
cp $1/include/oggplay/oggplay_query.h ./include/oggplay/oggplay_query.h
@ -30,14 +30,19 @@ cp $1/src/liboggplay/oggplay.c ./src/liboggplay/oggplay.c
cp $1/src/liboggplay/oggplay_callback.h ./src/liboggplay/oggplay_callback.h
cp $1/src/liboggplay/oggplay_tcp_reader.c ./src/liboggplay/oggplay_tcp_reader.c
cp $1/src/liboggplay/oggplay_query.c ./src/liboggplay/oggplay_query.c
sed s/\#include\ \"config_win32.h\"//g $1/src/liboggplay/oggplay_private.h >./src/liboggplay/oggplay_private.h1
sed s/\#include\ \<config.h\>/\#ifdef\ WIN32\\n\#include\ \"config_win32.h\"\\n\#else\\n\#include\ \<config.h\>\\n\#endif/g ./src/liboggplay/oggplay_private.h1 >./src/liboggplay/oggplay_private.h
cp $1/src/liboggplay/cpu.c ./src/liboggplay/cpu.c
cp $1/src/liboggplay/cpu.h ./src/liboggplay/cpu.h
cp $1/src/liboggplay/oggplay_yuv2rgb_template.h ./src/liboggplay/oggplay_yuv2rgb_template.h
cp $1/src/liboggplay/oggplay_yuv2rgb_x86.c ./src/liboggplay/oggplay_yuv2rgb_x86.c
cp $1/src/liboggplay/yuv2rgb_x86.h ./src/liboggplay/yuv2rgb_x86.h
cp $1/src/liboggplay/yuv2rgb_x86_vs.h ./src/liboggplay/yuv2rgb_x86_vs.h
sed 's/#include "config_win32.h"//g' $1/src/liboggplay/oggplay_private.h >./src/liboggplay/oggplay_private.h1
sed 's/#include <config.h>/#ifdef WIN32\
#include "config_win32.h"\
#else\
#include <config.h>\
#endif/g' ./src/liboggplay/oggplay_private.h1 >./src/liboggplay/oggplay_private.h
rm ./src/liboggplay/oggplay_private.h1
sed s/\#ifdef\ HAVE_INTTYPES_H/\#if\ HAVE_INTTYPES_H/g $1/src/liboggplay/oggplay_data.c >./src/liboggplay/oggplay_data.c
cd ./src/liboggplay
patch <../../yuv_disable_optimized.patch
cd ../..
patch -p3 <yuv2argb.patch
patch -p1 <bug468281_r3863.patch
patch -p1 <bug468281_r3864.patch
patch -p3 <bug468281_r3871.patch
patch -p3 < bug485291_yuv_align.patch

Просмотреть файл

@ -1,89 +0,0 @@
diff --git a/media/liboggplay/include/oggplay/oggplay_tools.h b/media/liboggplay/include/oggplay/oggplay_tools.h
index 30531a4..19fe709 100644
--- a/media/liboggplay/include/oggplay/oggplay_tools.h
+++ b/media/liboggplay/include/oggplay/oggplay_tools.h
@@ -75,6 +75,9 @@ void
oggplay_yuv2rgb(OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb);
void
+oggplay_yuv2argb(OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb);
+
+void
oggplay_yuv2bgr(OggPlayYUVChannels* yuv, OggPlayRGBChannels * rgb);
ogg_int64_t
diff --git a/media/liboggplay/src/liboggplay/config.h b/media/liboggplay/src/liboggplay/config.h
index e1754e4..46faa8a 100644
--- a/media/liboggplay/src/liboggplay/config.h
+++ b/media/liboggplay/src/liboggplay/config.h
@@ -86,3 +86,8 @@
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
#undef HAVE_GLUT
+
+#include "prcpucfg.h"
+#ifdef IS_BIG_ENDIAN
+#define WORDS_BIGENDIAN
+#endif
diff --git a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
index 0e2cef0..e070dc7 100644
--- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
+++ b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
@@ -396,6 +396,57 @@ void oggplay_yuv2rgb(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
}
}
+/* Vanilla implementation if YUV->ARGB conversion */
+void oggplay_yuv2argb(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
+
+ unsigned char * ptry = yuv->ptry;
+ unsigned char * ptru = yuv->ptru;
+ unsigned char * ptrv = yuv->ptrv;
+ unsigned char * ptro = rgb->ptro;
+ unsigned char * ptro2;
+ int i, j;
+
+ for (i = 0; i < yuv->y_height; i++) {
+ ptro2 = ptro;
+ for (j = 0; j < yuv->y_width; j += 2) {
+
+ short pr, pg, pb, y;
+ short r, g, b;
+
+ pr = (-56992 + ptrv[j/2] * 409) >> 8;
+ pg = (34784 - ptru[j/2] * 100 - ptrv[j/2] * 208) >> 8;
+ pb = (-70688 + ptru[j/2] * 516) >> 8;
+
+ y = 298*ptry[j] >> 8;
+ r = y + pr;
+ g = y + pg;
+ b = y + pb;
+
+ *ptro2++ = 255;
+ *ptro2++ = CLAMP(r);
+ *ptro2++ = CLAMP(g);
+ *ptro2++ = CLAMP(b);
+
+ y = 298*ptry[j + 1] >> 8;
+ r = y + pr;
+ g = y + pg;
+ b = y + pb;
+
+ *ptro2++ = 255;
+ *ptro2++ = CLAMP(r);
+ *ptro2++ = CLAMP(g);
+ *ptro2++ = CLAMP(b);
+ }
+ ptry += yuv->y_width;
+ if (i & 1) {
+ ptru += yuv->uv_width;
+ ptrv += yuv->uv_width;
+ }
+ ptro += rgb->rgb_width * 4;
+ }
+}
+
+
/* Vanilla implementation of YUV->BGR conversion*/
void oggplay_yuv2bgr(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {

Просмотреть файл

@ -1,16 +0,0 @@
diff --git a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
index 8ace308..0e2cef0 100644
--- a/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
+++ b/media/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
@@ -54,7 +54,10 @@
* V = 0.615 R - 0.515 G - 0.100 B
*/
-#if defined(__MMX__) || defined(__SSE__) || defined(__SSE2__) || defined(__SSE3__)
+// Optimized YUV to RGB conversion routine disabled due to generating
+// incorrect colours. See Annodex trac ticket 421:
+// http://trac.annodex.net/ticket/421
+#if 0 //defined(__MMX__) || defined(__SSE__) || defined(__SSE2__) || defined(__SSE3__)
#if defined(WIN32)
#define restrict