diff options
| author | Martin Lambers <marlam@marlam.de> | 2012-01-28 10:53:11 +0100 |
|---|---|---|
| committer | Martin Lambers <marlam@marlam.de> | 2012-01-28 10:53:11 +0100 |
| commit | 6496c90cbbbde5560aa7b147557ca469055777e1 (patch) | |
| tree | 33163127f68a665adc381bb146b3de8a1f27222a | |
| parent | 4fe593c1918edfacf5914c4b0d2777514ad4ef78 (diff) | |
| download | bino-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-- | AUTHORS | 1 | ||||
| -rw-r--r-- | src/Makefile.am | 4 | ||||
| -rw-r--r-- | src/icons-local/input-layout-alternating-left-right.ipe | 260 | ||||
| -rw-r--r-- | src/icons-local/input-layout-alternating-left-right.png | bin | 0 -> 861 bytes | |||
| -rw-r--r-- | src/icons-local/input-layout-alternating-right-left.ipe | 260 | ||||
| -rw-r--r-- | src/icons-local/input-layout-alternating-right-left.png | bin | 0 -> 872 bytes | |||
| -rw-r--r-- | src/main.cpp | 6 | ||||
| -rw-r--r-- | src/media_data.cpp | 18 | ||||
| -rw-r--r-- | src/media_data.h | 4 | ||||
| -rw-r--r-- | src/media_input.cpp | 18 | ||||
| -rw-r--r-- | src/media_object.cpp | 232 | ||||
| -rw-r--r-- | src/media_object.h | 8 | ||||
| -rw-r--r-- | src/player_qt.cpp | 44 |
13 files changed, 742 insertions, 113 deletions
@@ -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 Binary files differnew file mode 100644 index 0000000..44fbec7 --- /dev/null +++ b/src/icons-local/input-layout-alternating-left-right.png 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 Binary files differnew file mode 100644 index 0000000..3e31ff6 --- /dev/null +++ b/src/icons-local/input-layout-alternating-right-left.png 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; |
