summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Lambers <marlam@marlam.de>2012-01-28 10:53:11 +0100
committerMartin Lambers <marlam@marlam.de>2012-01-28 10:53:11 +0100
commit6496c90cbbbde5560aa7b147557ca469055777e1 (patch)
tree33163127f68a665adc381bb146b3de8a1f27222a
parent4fe593c1918edfacf5914c4b0d2777514ad4ef78 (diff)
downloadbino-6496c90cbbbde5560aa7b147557ca469055777e1.tar.gz
Add support for alternating left/right video frames, as used for MPO stereo images.
This is based on the discussion in #33366, with contributions by D. Matz. MPO image files should now work out of the box.
-rw-r--r--AUTHORS1
-rw-r--r--src/Makefile.am4
-rw-r--r--src/icons-local/input-layout-alternating-left-right.ipe260
-rw-r--r--src/icons-local/input-layout-alternating-left-right.pngbin0 -> 861 bytes
-rw-r--r--src/icons-local/input-layout-alternating-right-left.ipe260
-rw-r--r--src/icons-local/input-layout-alternating-right-left.pngbin0 -> 872 bytes
-rw-r--r--src/main.cpp6
-rw-r--r--src/media_data.cpp18
-rw-r--r--src/media_data.h4
-rw-r--r--src/media_input.cpp18
-rw-r--r--src/media_object.cpp232
-rw-r--r--src/media_object.h8
-rw-r--r--src/player_qt.cpp44
13 files changed, 742 insertions, 113 deletions
diff --git a/AUTHORS b/AUTHORS
index 4aa750b..73c5c7d 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,6 +4,7 @@ Martin Lambers
Current version:
Martin Lambers
Daniel Schaal
+D. Matz
Version 1.2.1:
Frédéric Devernay
diff --git a/src/Makefile.am b/src/Makefile.am
index 0425a3f..f095d2a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2010-2011
+# Copyright (C) 2010, 2011, 2012
# Martin Lambers <marlam@marlam.de>
#
# Copying and distribution of this file, with or without modification, are
@@ -28,6 +28,8 @@ ICONS_LOCAL_IPE = \
icons-local/input-layout-mono.ipe \
icons-local/input-layout-separate-left-right.ipe \
icons-local/input-layout-separate-right-left.ipe \
+ icons-local/input-layout-alternating-left-right.ipe \
+ icons-local/input-layout-alternating-right-left.ipe \
icons-local/input-layout-top-bottom.ipe \
icons-local/input-layout-top-bottom-half.ipe \
icons-local/input-layout-bottom-top.ipe \
diff --git a/src/icons-local/input-layout-alternating-left-right.ipe b/src/icons-local/input-layout-alternating-left-right.ipe
new file mode 100644
index 0000000..a67d02b
--- /dev/null
+++ b/src/icons-local/input-layout-alternating-left-right.ipe
@@ -0,0 +1,260 @@
+<?xml version="1.0"?>
+<!DOCTYPE ipe SYSTEM "ipe.dtd">
+<ipe version="70010" creator="Ipe 7.0.10">
+<info created="D:20110813152635" modified="D:20110813202517"/>
+<preamble>\renewcommand{\familydefault}{\sfdefault}</preamble>
+<ipestyle name="basic">
+<symbol name="arrow/arc(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/farc(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="mark/circle(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</symbol>
+<symbol name="mark/disk(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+</path>
+</symbol>
+<symbol name="mark/fdisk(sfx)" transformations="translations">
+<group>
+<path fill="sym-stroke" fillrule="eofill">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+<path fill="sym-fill">
+0.4 0 0 0.4 0 0 e
+</path>
+</group>
+</symbol>
+<symbol name="mark/box(sx)" transformations="translations">
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</symbol>
+<symbol name="mark/square(sx)" transformations="translations">
+<path fill="sym-stroke">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+</path>
+</symbol>
+<symbol name="mark/fsquare(sfx)" transformations="translations">
+<group>
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+<path fill="sym-fill">
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="mark/cross(sx)" transformations="translations">
+<group>
+<path fill="sym-stroke">
+-0.43 -0.57 m
+0.57 0.43 l
+0.43 0.57 l
+-0.57 -0.43 l
+h
+</path>
+<path fill="sym-stroke">
+-0.43 0.57 m
+0.57 -0.43 l
+0.43 -0.57 l
+-0.57 0.43 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="arrow/fnormal(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/pointed(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/fpointed(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/linear(spx)">
+<path stroke="sym-stroke" pen="sym-pen">
+-1 0.333 m
+0 0 l
+-1 -0.333 l
+</path>
+</symbol>
+<symbol name="arrow/fdouble(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/double(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<pen name="heavier" value="0.8"/>
+<pen name="fat" value="1.2"/>
+<pen name="ultrafat" value="2"/>
+<symbolsize name="large" value="5"/>
+<symbolsize name="small" value="2"/>
+<symbolsize name="tiny" value="1.1"/>
+<arrowsize name="large" value="10"/>
+<arrowsize name="small" value="5"/>
+<arrowsize name="tiny" value="3"/>
+<color name="red" value="1 0 0"/>
+<color name="green" value="0 1 0"/>
+<color name="blue" value="0 0 1"/>
+<color name="yellow" value="1 1 0"/>
+<color name="orange" value="1 0.647 0"/>
+<color name="gold" value="1 0.843 0"/>
+<color name="purple" value="0.627 0.125 0.941"/>
+<color name="gray" value="0.745"/>
+<color name="brown" value="0.647 0.165 0.165"/>
+<color name="navy" value="0 0 0.502"/>
+<color name="pink" value="1 0.753 0.796"/>
+<color name="seagreen" value="0.18 0.545 0.341"/>
+<color name="turquoise" value="0.251 0.878 0.816"/>
+<color name="violet" value="0.933 0.51 0.933"/>
+<color name="darkblue" value="0 0 0.545"/>
+<color name="darkcyan" value="0 0.545 0.545"/>
+<color name="darkgray" value="0.663"/>
+<color name="darkgreen" value="0 0.392 0"/>
+<color name="darkmagenta" value="0.545 0 0.545"/>
+<color name="darkorange" value="1 0.549 0"/>
+<color name="darkred" value="0.545 0 0"/>
+<color name="lightblue" value="0.678 0.847 0.902"/>
+<color name="lightcyan" value="0.878 1 1"/>
+<color name="lightgray" value="0.827"/>
+<color name="lightgreen" value="0.565 0.933 0.565"/>
+<color name="lightyellow" value="1 1 0.878"/>
+<dashstyle name="dashed" value="[4] 0"/>
+<dashstyle name="dotted" value="[1 3] 0"/>
+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>
+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>
+<textsize name="large" value="\large"/>
+<textsize name="small" value="\small"/>
+<textsize name="tiny" value="\tiny"/>
+<textsize name="Large" value="\Large"/>
+<textsize name="LARGE" value="\LARGE"/>
+<textsize name="huge" value="\huge"/>
+<textsize name="Huge" value="\Huge"/>
+<textsize name="footnote" value="\footnotesize"/>
+<textstyle name="center" begin="\begin{center}" end="\end{center}"/>
+<textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/>
+<textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/>
+<gridsize name="4 pts" value="4"/>
+<gridsize name="8 pts (~3 mm)" value="8"/>
+<gridsize name="16 pts (~6 mm)" value="16"/>
+<gridsize name="32 pts (~12 mm)" value="32"/>
+<gridsize name="10 pts (~3.5 mm)" value="10"/>
+<gridsize name="20 pts (~7 mm)" value="20"/>
+<gridsize name="14 pts (~5 mm)" value="14"/>
+<gridsize name="28 pts (~10 mm)" value="28"/>
+<gridsize name="56 pts (~20 mm)" value="56"/>
+<anglesize name="90 deg" value="90"/>
+<anglesize name="60 deg" value="60"/>
+<anglesize name="45 deg" value="45"/>
+<anglesize name="30 deg" value="30"/>
+<anglesize name="22.5 deg" value="22.5"/>
+<tiling name="falling" angle="-60" step="4" width="1"/>
+<tiling name="rising" angle="30" step="4" width="1"/>
+</ipestyle>
+<page>
+<layer name="alpha"/>
+<view layers="alpha" active="alpha"/>
+<path layer="alpha" fill="white">
+128 768 m
+128 720 l
+144 720 l
+144 768 l
+h
+</path>
+<path stroke="black" fill="green">
+64 768 m
+64 720 l
+128 720 l
+128 768 l
+h
+</path>
+<text transformations="translations" pos="64 752" stroke="black" type="minipage" width="64" valign="top" size="Huge" style="center">\textbf{L}</text>
+<path matrix="1 0 0 1 80 0" stroke="black" fill="red">
+64 768 m
+64 720 l
+128 720 l
+128 768 l
+h
+</path>
+<text matrix="1 0 0 1 80 0" transformations="translations" pos="64 752" stroke="black" type="minipage" width="64" valign="top" size="Huge" style="center">\textbf{R}</text>
+</page>
+</ipe>
diff --git a/src/icons-local/input-layout-alternating-left-right.png b/src/icons-local/input-layout-alternating-left-right.png
new file mode 100644
index 0000000..44fbec7
--- /dev/null
+++ b/src/icons-local/input-layout-alternating-left-right.png
Binary files differ
diff --git a/src/icons-local/input-layout-alternating-right-left.ipe b/src/icons-local/input-layout-alternating-right-left.ipe
new file mode 100644
index 0000000..eca9a4b
--- /dev/null
+++ b/src/icons-local/input-layout-alternating-right-left.ipe
@@ -0,0 +1,260 @@
+<?xml version="1.0"?>
+<!DOCTYPE ipe SYSTEM "ipe.dtd">
+<ipe version="70010" creator="Ipe 7.0.10">
+<info created="D:20110813152635" modified="D:20110813202552"/>
+<preamble>\renewcommand{\familydefault}{\sfdefault}</preamble>
+<ipestyle name="basic">
+<symbol name="arrow/arc(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/farc(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="mark/circle(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</symbol>
+<symbol name="mark/disk(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+</path>
+</symbol>
+<symbol name="mark/fdisk(sfx)" transformations="translations">
+<group>
+<path fill="sym-stroke" fillrule="eofill">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+<path fill="sym-fill">
+0.4 0 0 0.4 0 0 e
+</path>
+</group>
+</symbol>
+<symbol name="mark/box(sx)" transformations="translations">
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</symbol>
+<symbol name="mark/square(sx)" transformations="translations">
+<path fill="sym-stroke">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+</path>
+</symbol>
+<symbol name="mark/fsquare(sfx)" transformations="translations">
+<group>
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+<path fill="sym-fill">
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="mark/cross(sx)" transformations="translations">
+<group>
+<path fill="sym-stroke">
+-0.43 -0.57 m
+0.57 0.43 l
+0.43 0.57 l
+-0.57 -0.43 l
+h
+</path>
+<path fill="sym-stroke">
+-0.43 0.57 m
+0.57 -0.43 l
+0.43 -0.57 l
+-0.57 0.43 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="arrow/fnormal(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/pointed(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/fpointed(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/linear(spx)">
+<path stroke="sym-stroke" pen="sym-pen">
+-1 0.333 m
+0 0 l
+-1 -0.333 l
+</path>
+</symbol>
+<symbol name="arrow/fdouble(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/double(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<pen name="heavier" value="0.8"/>
+<pen name="fat" value="1.2"/>
+<pen name="ultrafat" value="2"/>
+<symbolsize name="large" value="5"/>
+<symbolsize name="small" value="2"/>
+<symbolsize name="tiny" value="1.1"/>
+<arrowsize name="large" value="10"/>
+<arrowsize name="small" value="5"/>
+<arrowsize name="tiny" value="3"/>
+<color name="red" value="1 0 0"/>
+<color name="green" value="0 1 0"/>
+<color name="blue" value="0 0 1"/>
+<color name="yellow" value="1 1 0"/>
+<color name="orange" value="1 0.647 0"/>
+<color name="gold" value="1 0.843 0"/>
+<color name="purple" value="0.627 0.125 0.941"/>
+<color name="gray" value="0.745"/>
+<color name="brown" value="0.647 0.165 0.165"/>
+<color name="navy" value="0 0 0.502"/>
+<color name="pink" value="1 0.753 0.796"/>
+<color name="seagreen" value="0.18 0.545 0.341"/>
+<color name="turquoise" value="0.251 0.878 0.816"/>
+<color name="violet" value="0.933 0.51 0.933"/>
+<color name="darkblue" value="0 0 0.545"/>
+<color name="darkcyan" value="0 0.545 0.545"/>
+<color name="darkgray" value="0.663"/>
+<color name="darkgreen" value="0 0.392 0"/>
+<color name="darkmagenta" value="0.545 0 0.545"/>
+<color name="darkorange" value="1 0.549 0"/>
+<color name="darkred" value="0.545 0 0"/>
+<color name="lightblue" value="0.678 0.847 0.902"/>
+<color name="lightcyan" value="0.878 1 1"/>
+<color name="lightgray" value="0.827"/>
+<color name="lightgreen" value="0.565 0.933 0.565"/>
+<color name="lightyellow" value="1 1 0.878"/>
+<dashstyle name="dashed" value="[4] 0"/>
+<dashstyle name="dotted" value="[1 3] 0"/>
+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>
+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>
+<textsize name="large" value="\large"/>
+<textsize name="small" value="\small"/>
+<textsize name="tiny" value="\tiny"/>
+<textsize name="Large" value="\Large"/>
+<textsize name="LARGE" value="\LARGE"/>
+<textsize name="huge" value="\huge"/>
+<textsize name="Huge" value="\Huge"/>
+<textsize name="footnote" value="\footnotesize"/>
+<textstyle name="center" begin="\begin{center}" end="\end{center}"/>
+<textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/>
+<textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/>
+<gridsize name="4 pts" value="4"/>
+<gridsize name="8 pts (~3 mm)" value="8"/>
+<gridsize name="16 pts (~6 mm)" value="16"/>
+<gridsize name="32 pts (~12 mm)" value="32"/>
+<gridsize name="10 pts (~3.5 mm)" value="10"/>
+<gridsize name="20 pts (~7 mm)" value="20"/>
+<gridsize name="14 pts (~5 mm)" value="14"/>
+<gridsize name="28 pts (~10 mm)" value="28"/>
+<gridsize name="56 pts (~20 mm)" value="56"/>
+<anglesize name="90 deg" value="90"/>
+<anglesize name="60 deg" value="60"/>
+<anglesize name="45 deg" value="45"/>
+<anglesize name="30 deg" value="30"/>
+<anglesize name="22.5 deg" value="22.5"/>
+<tiling name="falling" angle="-60" step="4" width="1"/>
+<tiling name="rising" angle="30" step="4" width="1"/>
+</ipestyle>
+<page>
+<layer name="alpha"/>
+<view layers="alpha" active="alpha"/>
+<path layer="alpha" fill="white">
+128 768 m
+128 720 l
+144 720 l
+144 768 l
+h
+</path>
+<path stroke="black" fill="red">
+64 768 m
+64 720 l
+128 720 l
+128 768 l
+h
+</path>
+<text transformations="translations" pos="64 752" stroke="black" type="minipage" width="64" height="11.093" depth="6.12" valign="top" size="Huge" style="center">\textbf{R}</text>
+<path matrix="1 0 0 1 80 0" stroke="black" fill="green">
+64 768 m
+64 720 l
+128 720 l
+128 768 l
+h
+</path>
+<text matrix="1 0 0 1 80 0" transformations="translations" pos="64 752" stroke="black" type="minipage" width="64" height="11.093" depth="6.12" valign="top" size="Huge" style="center">\textbf{L}</text>
+</page>
+</ipe>
diff --git a/src/icons-local/input-layout-alternating-right-left.png b/src/icons-local/input-layout-alternating-right-left.png
new file mode 100644
index 0000000..3e31ff6
--- /dev/null
+++ b/src/icons-local/input-layout-alternating-right-left.png
Binary files differ
diff --git a/src/main.cpp b/src/main.cpp
index 95ddf0d..ae3457e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,7 @@
/*
* This file is part of bino, a 3D video player.
*
- * Copyright (C) 2010-2011
+ * Copyright (C) 2010, 2011, 2012
* Martin Lambers <marlam@marlam.de>
* Stefan Eilemann <eile@eyescale.ch>
* Frédéric Devernay <Frederic.Devernay@inrialpes.fr>
@@ -223,6 +223,8 @@ int main(int argc, char *argv[])
input_modes.push_back("mono");
input_modes.push_back("separate-left-right");
input_modes.push_back("separate-right-left");
+ input_modes.push_back("alternating-left-right");
+ input_modes.push_back("alternating-right-left");
input_modes.push_back("top-bottom");
input_modes.push_back("top-bottom-half");
input_modes.push_back("bottom-top");
@@ -398,6 +400,8 @@ int main(int argc, char *argv[])
" mono Single view.\n"
" separate-left-right Left/right separate streams, left first.\n"
" separate-right-left Left/right separate streams, right first.\n"
+ " alternating-left-right Left/right alternating, left first.\n"
+ " alternating-right-left Left/right alternating, right first.\n"
" top-bottom Left top, right bottom.\n"
" top-bottom-half Left top, right bottom, half height.\n"
" bottom-top Left bottom, right top.\n"
diff --git a/src/media_data.cpp b/src/media_data.cpp
index e3e01ed..0f37345 100644
--- a/src/media_data.cpp
+++ b/src/media_data.cpp
@@ -1,9 +1,10 @@
/*
* This file is part of bino, a 3D video player.
*
- * Copyright (C) 2010-2011
+ * Copyright (C) 2010, 2011, 2012
* Martin Lambers <marlam@marlam.de>
* Joe <joe@wpj.cz>
+ * D. Matz <bandregent@yahoo.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -133,6 +134,9 @@ std::string video_frame::stereo_layout_to_string(stereo_layout_t stereo_layout,
case separate:
s = stereo_layout_swap ? "separate-right-left" : "separate-left-right";
break;
+ case alternating:
+ s = stereo_layout_swap ? "alternating-right-left" : "alternating-left-right";
+ break;
case top_bottom:
s = stereo_layout_swap ? "bottom-top" : "top-bottom";
break;
@@ -169,6 +173,16 @@ void video_frame::stereo_layout_from_string(const std::string &s, stereo_layout_
stereo_layout = separate;
stereo_layout_swap = false;
}
+ else if (s == "alternating-right-left")
+ {
+ stereo_layout = alternating;
+ stereo_layout_swap = true;
+ }
+ else if (s == "alternating-left-right")
+ {
+ stereo_layout = alternating;
+ stereo_layout_swap = false;
+ }
else if (s == "bottom-top")
{
stereo_layout = top_bottom;
@@ -372,6 +386,7 @@ void video_frame::copy_plane(int view, int plane, void *buf) const
src_offset = 0;
break;
case separate:
+ case alternating:
src = static_cast<const char *>(data[view][plane]);
src_row_size = line_size[view][plane];
src_offset = 0;
@@ -395,6 +410,7 @@ void video_frame::copy_plane(int view, int plane, void *buf) const
break;
}
+ assert(src);
if (src_row_size == dst_row_size)
{
std::memcpy(dst, src + src_offset, lines * src_row_size);
diff --git a/src/media_data.h b/src/media_data.h
index 01e5b25..7b288f7 100644
--- a/src/media_data.h
+++ b/src/media_data.h
@@ -1,9 +1,10 @@
/*
* This file is part of bino, a 3D video player.
*
- * Copyright (C) 2010-2011
+ * Copyright (C) 2010, 2011, 2012
* Martin Lambers <marlam@marlam.de>
* Joe <joe@wpj.cz>
+ * D. Matz <bandregent@yahoo.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -101,6 +102,7 @@ public:
{
mono, // 1 video source: center view
separate, // 2 video sources: left and right view independent
+ alternating, // 2 video sources: left and right view consecutively
top_bottom, // 1 video source: left view top, right view bottom, both with full size
top_bottom_half,// 1 video source: left view top, right view bottom, both with half size
left_right, // 1 video source: left view left, right view right, both with full size
diff --git a/src/media_input.cpp b/src/media_input.cpp
index 0953075..724e05e 100644
--- a/src/media_input.cpp
+++ b/src/media_input.cpp
@@ -1,7 +1,7 @@
/*
* This file is part of bino, a 3D video player.
*
- * Copyright (C) 2010-2011
+ * Copyright (C) 2010, 2011, 2012
* Martin Lambers <marlam@marlam.de>
* Frédéric Devernay <frederic.devernay@inrialpes.fr>
* Joe <cuchac@email.cz>
@@ -578,14 +578,15 @@ void media_input::start_video_frame_read()
int o0, s0, o1, s1;
get_video_stream(0, o0, s0);
get_video_stream(1, o1, s1);
- _media_objects[o0].start_video_frame_read(s0);
- _media_objects[o1].start_video_frame_read(s1);
+ _media_objects[o0].start_video_frame_read(s0, 1);
+ _media_objects[o1].start_video_frame_read(s1, 1);
}
else
{
int o, s;
get_video_stream(_active_video_stream, o, s);
- _media_objects[o].start_video_frame_read(s);
+ _media_objects[o].start_video_frame_read(s,
+ _video_frame.stereo_layout == video_frame::alternating ? 2 : 1);
}
_have_active_video_read = true;
}
@@ -626,10 +627,13 @@ video_frame media_input::finish_video_frame_read()
if (f.is_valid())
{
frame = _video_frame;
- for (int p = 0; p < 3; p++)
+ for (int v = 0; v < 2; v++)
{
- frame.data[0][p] = f.data[0][p];
- frame.line_size[0][p] = f.line_size[0][p];
+ for (int p = 0; p < 3; p++)
+ {
+ frame.data[v][p] = f.data[v][p];
+ frame.line_size[v][p] = f.line_size[v][p];
+ }
}
frame.presentation_time = f.presentation_time;
}
diff --git a/src/media_object.cpp b/src/media_object.cpp
index c1600aa..e4565f1 100644
--- a/src/media_object.cpp
+++ b/src/media_object.cpp
@@ -1,10 +1,11 @@
/*
* This file is part of bino, a 3D video player.
*
- * Copyright (C) 2010-2011
+ * Copyright (C) 2010, 2011, 2012
* Martin Lambers <marlam@marlam.de>
* Frédéric Devernay <frederic.devernay@inrialpes.fr>
* Joe <cuchac@email.cz>
+ * D. Matz <bandregent@yahoo.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -86,11 +87,16 @@ private:
struct ffmpeg_stuff *_ffmpeg;
int _video_stream;
video_frame _frame;
+ int _raw_frames;
int64_t handle_timestamp(int64_t timestamp);
public:
video_decode_thread(const std::string &url, struct ffmpeg_stuff *ffmpeg, int video_stream);
+ void set_raw_frames(int raw_frames)
+ {
+ _raw_frames = raw_frames;
+ }
void run();
const video_frame &frame()
{
@@ -158,15 +164,17 @@ struct ffmpeg_stuff
std::vector<int> video_streams;
std::vector<AVCodecContext *> video_codec_ctxs;
std::vector<video_frame> video_frame_templates;
- std::vector<struct SwsContext *> video_img_conv_ctxs;
+ std::vector<struct SwsContext *> video_sws_ctxs;
std::vector<AVCodec *> video_codecs;
std::vector<std::deque<AVPacket> > video_packet_queues;
std::vector<mutex> video_packet_queue_mutexes;
std::vector<AVPacket> video_packets;
std::vector<video_decode_thread> video_decode_threads;
std::vector<AVFrame *> video_frames;
- std::vector<AVFrame *> video_out_frames;
+ std::vector<AVFrame *> video_buffered_frames;
std::vector<uint8_t *> video_buffers;
+ std::vector<AVFrame *> video_sws_frames;
+ std::vector<uint8_t *> video_sws_buffers;
std::vector<int64_t> video_last_timestamps;
std::vector<int> audio_streams;
@@ -488,6 +496,13 @@ void media_object::set_video_frame_template(int index, int width_before_avcodec_
{
video_frame_template.stereo_layout = video_frame::top_bottom;
}
+ /* MPO files are alternating-left-right. */
+ if (_url.length() > 4
+ && (_url.substr(_url.length() - 4) == ".mpo"
+ || _url.substr(_url.length() - 4) == ".MPO"))
+ {
+ video_frame_template.stereo_layout = video_frame::alternating;
+ }
/* Determine the input mode by looking at the file name.
* This should be compatible to these conventions:
* http://www.tru3d.com/technology/3D_Media_Formats_Software.php?file=TriDef%20Supported%203D%20Formats */
@@ -637,6 +652,11 @@ void media_object::set_video_frame_template(int index, int width_before_avcodec_
video_frame_template.stereo_layout = video_frame::even_odd_rows;
video_frame_template.stereo_layout_swap = (val == "row_interleaved_rl");
}
+ else if (val == "block_lr" || val == "block_rl")
+ {
+ video_frame_template.stereo_layout = video_frame::alternating;
+ video_frame_template.stereo_layout_swap = (val == "block_rl");
+ }
else if (!val.empty())
{
msg::wrn(_("%s video stream %d: Unsupported stereo layout %s."),
@@ -858,29 +878,37 @@ void media_object::open(const std::string &url, const device_request &dev_reques
av_init_packet(&(_ffmpeg->video_packets[j]));
_ffmpeg->video_decode_threads.push_back(video_decode_thread(_url, _ffmpeg, j));
_ffmpeg->video_frames.push_back(avcodec_alloc_frame());
- if (!_ffmpeg->video_frames[j])
+ _ffmpeg->video_buffered_frames.push_back(avcodec_alloc_frame());
+ enum PixelFormat frame_fmt = (_ffmpeg->video_frame_templates[j].layout == video_frame::bgra32
+ ? PIX_FMT_BGRA : _ffmpeg->video_codec_ctxs[j]->pix_fmt);
+ int frame_bufsize = (avpicture_get_size(frame_fmt,
+ _ffmpeg->video_codec_ctxs[j]->width, _ffmpeg->video_codec_ctxs[j]->height));
+ _ffmpeg->video_buffers.push_back(static_cast<uint8_t *>(av_malloc(frame_bufsize)));
+ avpicture_fill(reinterpret_cast<AVPicture *>(_ffmpeg->video_buffered_frames[j]), _ffmpeg->video_buffers[j],
+ frame_fmt, _ffmpeg->video_codec_ctxs[j]->width, _ffmpeg->video_codec_ctxs[j]->height);
+ if (!_ffmpeg->video_frames[j] || !_ffmpeg->video_buffered_frames[j] || !_ffmpeg->video_buffers[j])
{
throw exc(HERE + ": " + strerror(ENOMEM));
}
if (_ffmpeg->video_frame_templates[j].layout == video_frame::bgra32)
{
// Initialize things needed for software pixel format conversion
- int bufsize = avpicture_get_size(PIX_FMT_BGRA,
+ int sws_bufsize = avpicture_get_size(PIX_FMT_BGRA,
_ffmpeg->video_codec_ctxs[j]->width, _ffmpeg->video_codec_ctxs[j]->height);
- _ffmpeg->video_out_frames.push_back(avcodec_alloc_frame());
- _ffmpeg->video_buffers.push_back(static_cast<uint8_t *>(av_malloc(bufsize)));
- if (!_ffmpeg->video_out_frames[j] || !_ffmpeg->video_buffers[j])
+ _ffmpeg->video_sws_frames.push_back(avcodec_alloc_frame());
+ _ffmpeg->video_sws_buffers.push_back(static_cast<uint8_t *>(av_malloc(sws_bufsize)));
+ if (!_ffmpeg->video_sws_frames[j] || !_ffmpeg->video_sws_buffers[j])
{
throw exc(HERE + ": " + strerror(ENOMEM));
}
- avpicture_fill(reinterpret_cast<AVPicture *>(_ffmpeg->video_out_frames[j]), _ffmpeg->video_buffers[j],
+ avpicture_fill(reinterpret_cast<AVPicture *>(_ffmpeg->video_sws_frames[j]), _ffmpeg->video_sws_buffers[j],
PIX_FMT_BGRA, _ffmpeg->video_codec_ctxs[j]->width, _ffmpeg->video_codec_ctxs[j]->height);
// Call sws_getCachedContext(NULL, ...) instead of sws_getContext(...) just to avoid a deprecation warning.
- _ffmpeg->video_img_conv_ctxs.push_back(sws_getCachedContext(NULL,
+ _ffmpeg->video_sws_ctxs.push_back(sws_getCachedContext(NULL,
_ffmpeg->video_codec_ctxs[j]->width, _ffmpeg->video_codec_ctxs[j]->height, _ffmpeg->video_codec_ctxs[j]->pix_fmt,
_ffmpeg->video_codec_ctxs[j]->width, _ffmpeg->video_codec_ctxs[j]->height, PIX_FMT_BGRA,
SWS_POINT, NULL, NULL, NULL));
- if (!_ffmpeg->video_img_conv_ctxs[j])
+ if (!_ffmpeg->video_sws_ctxs[j])
{
throw exc(str::asprintf(_("%s video stream %d: Cannot initialize conversion context."),
_url.c_str(), j + 1));
@@ -888,9 +916,9 @@ void media_object::open(const std::string &url, const device_request &dev_reques
}
else
{
- _ffmpeg->video_out_frames.push_back(NULL);
- _ffmpeg->video_buffers.push_back(NULL);
- _ffmpeg->video_img_conv_ctxs.push_back(NULL);
+ _ffmpeg->video_sws_frames.push_back(NULL);
+ _ffmpeg->video_sws_buffers.push_back(NULL);
+ _ffmpeg->video_sws_ctxs.push_back(NULL);
}
_ffmpeg->video_last_timestamps.push_back(std::numeric_limits<int64_t>::min());
}
@@ -1334,7 +1362,7 @@ void read_thread::reset()
}
video_decode_thread::video_decode_thread(const std::string &url, struct ffmpeg_stuff *ffmpeg, int video_stream) :
- _url(url), _ffmpeg(ffmpeg), _video_stream(video_stream), _frame()
+ _url(url), _ffmpeg(ffmpeg), _video_stream(video_stream), _frame(), _raw_frames(1)
{
}
@@ -1350,87 +1378,115 @@ int64_t video_decode_thread::handle_timestamp(int64_t timestamp)
void video_decode_thread::run()
{
- int frame_finished = 0;
- do
+ _frame = _ffmpeg->video_frame_templates[_video_stream];
+ for (int raw_frame = 0; raw_frame < _raw_frames; raw_frame++)
{
- bool empty;
+ int frame_finished = 0;
do
{
- _ffmpeg->video_packet_queue_mutexes[_video_stream].lock();
- empty = _ffmpeg->video_packet_queues[_video_stream].empty();
- _ffmpeg->video_packet_queue_mutexes[_video_stream].unlock();
- if (empty)
+ bool empty;
+ do
{
- if (_ffmpeg->reader->eof())
+ _ffmpeg->video_packet_queue_mutexes[_video_stream].lock();
+ empty = _ffmpeg->video_packet_queues[_video_stream].empty();
+ _ffmpeg->video_packet_queue_mutexes[_video_stream].unlock();
+ if (empty)
{
- _frame = video_frame();
- return;
+ if (_ffmpeg->reader->eof())
+ {
+ if (raw_frame == 1)
+ {
+ _frame.data[1][0] = _frame.data[0][0];
+ _frame.data[1][1] = _frame.data[0][1];
+ _frame.data[1][2] = _frame.data[0][2];
+ _frame.line_size[1][0] = _frame.line_size[0][0];
+ _frame.line_size[1][1] = _frame.line_size[0][1];
+ _frame.line_size[1][2] = _frame.line_size[0][2];
+ }
+ else
+ {
+ _frame = video_frame();
+ }
+ return;
+ }
+ msg::dbg(_url + ": video stream " + str::from(_video_stream) + ": need to wait for packets...");
+ _ffmpeg->reader->start();
+ _ffmpeg->reader->finish();
}
- msg::dbg(_url + ": video stream " + str::from(_video_stream) + ": need to wait for packets...");
- _ffmpeg->reader->start();
- _ffmpeg->reader->finish();
}
+ while (empty);
+ av_free_packet(&(_ffmpeg->video_packets[_video_stream]));
+ _ffmpeg->video_packet_queue_mutexes[_video_stream].lock();
+ _ffmpeg->video_packets[_video_stream] = _ffmpeg->video_packet_queues[_video_stream].front();
+ _ffmpeg->video_packet_queues[_video_stream].pop_front();
+ _ffmpeg->video_packet_queue_mutexes[_video_stream].unlock();
+ _ffmpeg->reader->start(); // Refill the packet queue
+ avcodec_decode_video2(_ffmpeg->video_codec_ctxs[_video_stream],
+ _ffmpeg->video_frames[_video_stream], &frame_finished,
+ &(_ffmpeg->video_packets[_video_stream]));
}
- while (empty);
- av_free_packet(&(_ffmpeg->video_packets[_video_stream]));
- _ffmpeg->video_packet_queue_mutexes[_video_stream].lock();
- _ffmpeg->video_packets[_video_stream] = _ffmpeg->video_packet_queues[_video_stream].front();
- _ffmpeg->video_packet_queues[_video_stream].pop_front();
- _ffmpeg->video_packet_queue_mutexes[_video_stream].unlock();
- _ffmpeg->reader->start(); // Refill the packet queue
- avcodec_decode_video2(_ffmpeg->video_codec_ctxs[_video_stream],
- _ffmpeg->video_frames[_video_stream], &frame_finished,
- &(_ffmpeg->video_packets[_video_stream]));
- }
- while (!frame_finished);
+ while (!frame_finished);
- _frame = _ffmpeg->video_frame_templates[_video_stream];
- if (_frame.layout == video_frame::bgra32)
- {
- sws_scale(_ffmpeg->video_img_conv_ctxs[_video_stream],
- _ffmpeg->video_frames[_video_stream]->data,
- _ffmpeg->video_frames[_video_stream]->linesize,
- 0, _frame.raw_height,
- _ffmpeg->video_out_frames[_video_stream]->data,
- _ffmpeg->video_out_frames[_video_stream]->linesize);
- // TODO: Handle sws_scale errors. How?
- _frame.data[0][0] = _ffmpeg->video_out_frames[_video_stream]->data[0];
- _frame.line_size[0][0] = _ffmpeg->video_out_frames[_video_stream]->linesize[0];
- }
- else
- {
- _frame.data[0][0] = _ffmpeg->video_frames[_video_stream]->data[0];
- _frame.data[0][1] = _ffmpeg->video_frames[_video_stream]->data[1];
- _frame.data[0][2] = _ffmpeg->video_frames[_video_stream]->data[2];
- _frame.line_size[0][0] = _ffmpeg->video_frames[_video_stream]->linesize[0];
- _frame.line_size[0][1] = _ffmpeg->video_frames[_video_stream]->linesize[1];
- _frame.line_size[0][2] = _ffmpeg->video_frames[_video_stream]->linesize[2];
- }
+ if (_frame.layout == video_frame::bgra32)
+ {
+ sws_scale(_ffmpeg->video_sws_ctxs[_video_stream],
+ _ffmpeg->video_frames[_video_stream]->data,
+ _ffmpeg->video_frames[_video_stream]->linesize,
+ 0, _frame.raw_height,
+ _ffmpeg->video_sws_frames[_video_stream]->data,
+ _ffmpeg->video_sws_frames[_video_stream]->linesize);
+ // TODO: Handle sws_scale errors. How?
+ _frame.data[raw_frame][0] = _ffmpeg->video_sws_frames[_video_stream]->data[0];
+ _frame.line_size[raw_frame][0] = _ffmpeg->video_sws_frames[_video_stream]->linesize[0];
+ }
+ else
+ {
+ const AVFrame *src_frame = _ffmpeg->video_frames[_video_stream];
+ if (_raw_frames == 2 && raw_frame == 0)
+ {
+ // We need to buffer the data because FFmpeg will clubber it when decoding the next frame.
+ av_picture_copy(reinterpret_cast<AVPicture *>(_ffmpeg->video_buffered_frames[_video_stream]),
+ reinterpret_cast<AVPicture *>(_ffmpeg->video_frames[_video_stream]),
+ static_cast<enum PixelFormat>(_ffmpeg->video_codec_ctxs[_video_stream]->pix_fmt),
+ _ffmpeg->video_codec_ctxs[_video_stream]->width,
+ _ffmpeg->video_codec_ctxs[_video_stream]->height);
+ src_frame = _ffmpeg->video_buffered_frames[_video_stream];
+ }
+ _frame.data[raw_frame][0] = src_frame->data[0];
+ _frame.data[raw_frame][1] = src_frame->data[1];
+ _frame.data[raw_frame][2] = src_frame->data[2];
+ _frame.line_size[raw_frame][0] = src_frame->linesize[0];
+ _frame.line_size[raw_frame][1] = src_frame->linesize[1];
+ _frame.line_size[raw_frame][2] = src_frame->linesize[2];
+ }
- if (_ffmpeg->video_packets[_video_stream].dts != static_cast<int64_t>(AV_NOPTS_VALUE))
- {
- _frame.presentation_time = handle_timestamp(_ffmpeg->video_packets[_video_stream].dts * 1000000
- * _ffmpeg->format_ctx->streams[_ffmpeg->video_streams[_video_stream]]->time_base.num
- / _ffmpeg->format_ctx->streams[_ffmpeg->video_streams[_video_stream]]->time_base.den);
- }
- else if (_ffmpeg->video_last_timestamps[_video_stream] != std::numeric_limits<int64_t>::min())
- {
- msg::dbg(_url + ": video stream " + str::from(_video_stream)
- + ": no timestamp available, using a questionable guess");
- _frame.presentation_time = _ffmpeg->video_last_timestamps[_video_stream];
- }
- else
- {
- msg::dbg(_url + ": video stream " + str::from(_video_stream)
- + ": no timestamp available, using a bad guess");
- _frame.presentation_time = _ffmpeg->pos;
+ if (_ffmpeg->video_packets[_video_stream].dts != static_cast<int64_t>(AV_NOPTS_VALUE))
+ {
+ _frame.presentation_time = handle_timestamp(_ffmpeg->video_packets[_video_stream].dts * 1000000
+ * _ffmpeg->format_ctx->streams[_ffmpeg->video_streams[_video_stream]]->time_base.num
+ / _ffmpeg->format_ctx->streams[_ffmpeg->video_streams[_video_stream]]->time_base.den);
+ }
+ else if (_ffmpeg->video_last_timestamps[_video_stream] != std::numeric_limits<int64_t>::min())
+ {
+ msg::dbg(_url + ": video stream " + str::from(_video_stream)
+ + ": no timestamp available, using a questionable guess");
+ _frame.presentation_time = _ffmpeg->video_last_timestamps[_video_stream];
+ }
+ else
+ {
+ msg::dbg(_url + ": video stream " + str::from(_video_stream)
+ + ": no timestamp available, using a bad guess");
+ _frame.presentation_time = _ffmpeg->pos;
+ }
}
}
-void media_object::start_video_frame_read(int video_stream)
+void media_object::start_video_frame_read(int video_stream, int raw_frames)
{
assert(video_stream >= 0);
assert(video_stream < video_streams());
+ assert(raw_frames == 1 || raw_frames == 2);
+ _ffmpeg->video_decode_threads[video_stream].set_raw_frames(raw_frames);
_ffmpeg->video_decode_threads[video_stream].start();
}
@@ -1867,14 +1923,22 @@ void media_object::close()
{
av_free(_ffmpeg->video_frames[i]);
}
- for (size_t i = 0; i < _ffmpeg->video_out_frames.size(); i++)
+ for (size_t i = 0; i < _ffmpeg->video_buffered_frames.size(); i++)
{
- av_free(_ffmpeg->video_out_frames[i]);
+ av_free(_ffmpeg->video_buffered_frames[i]);
}
for (size_t i = 0; i < _ffmpeg->video_buffers.size(); i++)
{
av_free(_ffmpeg->video_buffers[i]);
}
+ for (size_t i = 0; i < _ffmpeg->video_sws_frames.size(); i++)
+ {
+ av_free(_ffmpeg->video_sws_frames[i]);
+ }
+ for (size_t i = 0; i < _ffmpeg->video_sws_buffers.size(); i++)
+ {
+ av_free(_ffmpeg->video_sws_buffers[i]);
+ }
for (size_t i = 0; i < _ffmpeg->video_codec_ctxs.size(); i++)
{
if (i < _ffmpeg->video_codecs.size() && _ffmpeg->video_codecs[i])
@@ -1882,9 +1946,9 @@ void media_object::close()
avcodec_close(_ffmpeg->video_codec_ctxs[i]);
}
}
- for (size_t i = 0; i < _ffmpeg->video_img_conv_ctxs.size(); i++)
+ for (size_t i = 0; i < _ffmpeg->video_sws_ctxs.size(); i++)
{
- sws_freeContext(_ffmpeg->video_img_conv_ctxs[i]);
+ sws_freeContext(_ffmpeg->video_sws_ctxs[i]);
}
for (size_t i = 0; i < _ffmpeg->video_packet_queues.size(); i++)
{
diff --git a/src/media_object.h b/src/media_object.h
index 9e52da2..9910993 100644
--- a/src/media_object.h
+++ b/src/media_object.h
@@ -1,7 +1,7 @@
/*
* This file is part of bino, a 3D video player.
*
- * Copyright (C) 2010-2011
+ * Copyright (C) 2010, 2011, 2012
* Martin Lambers <marlam@marlam.de>
* Joe <cuchac@email.cz>
*
@@ -109,8 +109,10 @@ public:
* Access media data
*/
- /* Start to read a video frame asynchronously (in a separate thread). */
- void start_video_frame_read(int video_stream);
+ /* Start to read a video frame asynchronously (in a separate thread).
+ * The value of 'raw_frames' must be 1 or 2. If it is 2, the two views of the frame
+ * are read from two consecutive raw video frames. */
+ void start_video_frame_read(int video_stream, int raw_frames);
/* Wait for the video frame reading to finish, and return the frame.
* An invalid frame means that EOF was reached. */
video_frame finish_video_frame_read(int video_stream);
diff --git a/src/player_qt.cpp b/src/player_qt.cpp
index 8c5fe13..94a7874 100644
--- a/src/player_qt.cpp
+++ b/src/player_qt.cpp
@@ -1,11 +1,12 @@
/*
* This file is part of bino, a 3D video player.
*
- * Copyright (C) 2010-2012
+ * Copyright (C) 2010, 2011, 2012
* Martin Lambers <marlam@marlam.de>
* Frédéric Devernay <Frederic.Devernay@inrialpes.fr>
* Joe <cuchac@email.cz>
* Daniel Schaal <farbing@web.de>
+ * D. Matz <bandregent@yahoo.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -199,6 +200,8 @@ in_out_widget::in_out_widget(QSettings *settings, const player_qt_internal *play
_input_combobox->addItem(QIcon(":icons-local/input-layout-mono.png"), _("2D"));
_input_combobox->addItem(QIcon(":icons-local/input-layout-separate-left-right.png"), _("Separate streams, left first"));
_input_combobox->addItem(QIcon(":icons-local/input-layout-separate-right-left.png"), _("Separate streams, right first"));
+ _input_combobox->addItem(QIcon(":icons-local/input-layout-alternating-left-right.png"), _("Alternating, left first"));
+ _input_combobox->addItem(QIcon(":icons-local/input-layout-alternating-right-left.png"), _("Alternating, right first"));
_input_combobox->addItem(QIcon(":icons-local/input-layout-top-bottom.png"), _("Top/bottom"));
_input_combobox->addItem(QIcon(":icons-local/input-layout-top-bottom-half.png"), _("Top/bottom, half height"));
_input_combobox->addItem(QIcon(":icons-local/input-layout-bottom-top.png"), _("Bottom/top"));
@@ -305,20 +308,23 @@ void in_out_widget::set_stereo_layout(video_frame::stereo_layout_t stereo_layout
case video_frame::separate:
_input_combobox->setCurrentIndex(stereo_layout_swap ? 2 : 1);
break;
+ case video_frame::alternating:
+ _input_combobox->setCurrentIndex(stereo_layout_swap ? 4 : 3);
+ break;
case video_frame::top_bottom:
- _input_combobox->setCurrentIndex(stereo_layout_swap ? 5 : 3);
+ _input_combobox->setCurrentIndex(stereo_layout_swap ? 7 : 5);
break;
case video_frame::top_bottom_half:
- _input_combobox->setCurrentIndex(stereo_layout_swap ? 6 : 4);
+ _input_combobox->setCurrentIndex(stereo_layout_swap ? 8 : 6);
break;
case video_frame::left_right:
- _input_combobox->setCurrentIndex(stereo_layout_swap ? 9: 7);
+ _input_combobox->setCurrentIndex(stereo_layout_swap ? 11: 9);
break;
case video_frame::left_right_half:
- _input_combobox->setCurrentIndex(stereo_layout_swap ? 10 : 8);
+ _input_combobox->setCurrentIndex(stereo_layout_swap ? 12 : 10);
break;
case video_frame::even_odd_rows:
- _input_combobox->setCurrentIndex(stereo_layout_swap ? 12 : 11);
+ _input_combobox->setCurrentIndex(stereo_layout_swap ? 14 : 13);
break;
}
_video_combobox->setEnabled(stereo_layout != video_frame::separate);
@@ -581,42 +587,50 @@ void in_out_widget::get_stereo_layout(video_frame::stereo_layout_t &stereo_layou
stereo_layout_swap = true;
break;
case 3:
- stereo_layout = video_frame::top_bottom;
+ stereo_layout = video_frame::alternating;
stereo_layout_swap = false;
break;
case 4:
+ stereo_layout = video_frame::alternating;
+ stereo_layout_swap = true;
+ break;
+ case 5:
+ stereo_layout = video_frame::top_bottom;
+ stereo_layout_swap = false;
+ break;
+ case 6:
stereo_layout = video_frame::top_bottom_half;
stereo_layout_swap = false;
break;
- case 5:
+ case 7:
stereo_layout = video_frame::top_bottom;
stereo_layout_swap = true;
break;
- case 6:
+ case 8:
stereo_layout = video_frame::top_bottom_half;
stereo_layout_swap = true;
break;
- case 7:
+ case 9:
stereo_layout = video_frame::left_right;
stereo_layout_swap = false;
break;
- case 8:
+ case 10:
stereo_layout = video_frame::left_right_half;
stereo_layout_swap = false;
break;
- case 9:
+ case 11:
stereo_layout = video_frame::left_right;
stereo_layout_swap = true;
break;
- case 10:
+ case 12:
stereo_layout = video_frame::left_right_half;
stereo_layout_swap = true;
break;
- case 11:
+ case 13:
stereo_layout = video_frame::even_odd_rows;
stereo_layout_swap = false;
break;
- case 12:
+ case 14:
stereo_layout = video_frame::even_odd_rows;
stereo_layout_swap = true;
break;