Various incomplete hacks on regions / audio mapping.
[dcpomatic.git] / src / wx / ffmpeg_content_dialog.cc
1 /* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
2
3 /*
4     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 */
21
22 #include <boost/lexical_cast.hpp>
23 #include "lib/ffmpeg_content.h"
24 #include "lib/playlist.h"
25 #include "ffmpeg_content_dialog.h"
26 #include "wx_util.h"
27 #include "audio_mapping_view.h"
28
29 using std::vector;
30 using std::string;
31 using std::cout;
32 using boost::shared_ptr;
33 using boost::lexical_cast;
34 using boost::dynamic_pointer_cast;
35
36 FFmpegContentDialog::FFmpegContentDialog (wxWindow* parent, shared_ptr<Playlist::Region> region)
37         : wxDialog (parent, wxID_ANY, _("Video"))
38         , _region (region)
39         , _content (dynamic_pointer_cast<FFmpegContent> (region->content))
40 {
41         wxFlexGridSizer* grid = new wxFlexGridSizer (3, 6, 6);
42         grid->AddGrowableCol (1, 1);
43
44         add_label_to_sizer (grid, this, _("Audio Stream"));
45         _audio_stream = new wxChoice (this, wxID_ANY);
46         grid->Add (_audio_stream, 1, wxEXPAND | wxALL, 6);
47         _audio_description = new wxStaticText (this, wxID_ANY, wxT (""));
48         grid->Add (_audio_description, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8);
49         
50         add_label_to_sizer (grid, this, _("Subtitle stream"));
51         _subtitle_stream = new wxChoice (this, wxID_ANY);
52         grid->Add (_subtitle_stream, 1, wxEXPAND | wxALL, 6);
53         grid->AddSpacer (0);
54
55         shared_ptr<FFmpegContent> content = _content.lock ();
56         assert (content);
57
58         _audio_stream->Clear ();
59         vector<FFmpegAudioStream> a = content->audio_streams ();
60         for (vector<FFmpegAudioStream>::iterator i = a.begin(); i != a.end(); ++i) {
61                 _audio_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (lexical_cast<string> (i->id))));
62         }
63         
64         if (content->audio_stream()) {
65                 checked_set (_audio_stream, lexical_cast<string> (content->audio_stream()->id));
66         }
67
68         _subtitle_stream->Clear ();
69         vector<FFmpegSubtitleStream> s = content->subtitle_streams ();
70         if (s.empty ()) {
71                 _subtitle_stream->Enable (false);
72         }
73         for (vector<FFmpegSubtitleStream>::iterator i = s.begin(); i != s.end(); ++i) {
74                 _subtitle_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (lexical_cast<string> (i->id))));
75         }
76         
77         if (content->subtitle_stream()) {
78                 checked_set (_subtitle_stream, lexical_cast<string> (content->subtitle_stream()->id));
79         } else {
80                 _subtitle_stream->SetSelection (wxNOT_FOUND);
81         }
82
83         wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
84
85         overall_sizer->Add (grid, 1, wxEXPAND | wxALL, 6);
86
87         _audio_mapping = new AudioMappingView (this);
88         _audio_mapping->set_mapping (region->audio_mapping);
89         overall_sizer->Add (_audio_mapping, 1, wxEXPAND | wxALL, 6);
90
91         wxSizer* buttons = CreateSeparatedButtonSizer (wxOK);
92         if (buttons) {
93                 overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
94         }
95
96         SetSizer (overall_sizer);
97         overall_sizer->Layout ();
98         overall_sizer->SetSizeHints (this);
99
100         _audio_stream->Connect    (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FFmpegContentDialog::audio_stream_changed), 0, this);
101         _subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FFmpegContentDialog::subtitle_stream_changed), 0, this);
102         _audio_mapping->Changed.connect (bind (&FFmpegContentDialog::audio_mapping_changed, this, _1));
103 }
104
105 void
106 FFmpegContentDialog::audio_stream_changed (wxCommandEvent &)
107 {
108         shared_ptr<FFmpegContent> c = _content.lock ();
109         if (!c) {
110                 return;
111         }
112         
113         vector<FFmpegAudioStream> a = c->audio_streams ();
114         vector<FFmpegAudioStream>::iterator i = a.begin ();
115         string const s = string_client_data (_audio_stream->GetClientObject (_audio_stream->GetSelection ()));
116         while (i != a.end() && lexical_cast<string> (i->id) != s) {
117                 ++i;
118         }
119
120         if (i != a.end ()) {
121                 c->set_audio_stream (*i);
122         }
123
124         if (!c->audio_stream ()) {
125                 _audio_description->SetLabel (wxT (""));
126         } else {
127                 wxString s;
128                 if (c->audio_channels() == 1) {
129                         s << _("1 channel");
130                 } else {
131                         s << c->audio_channels() << wxT (" ") << _("channels");
132                 }
133                 s << wxT (", ") << c->content_audio_frame_rate() << _("Hz");
134                 _audio_description->SetLabel (s);
135         }
136 }
137
138
139
140 void
141 FFmpegContentDialog::subtitle_stream_changed (wxCommandEvent &)
142 {
143         shared_ptr<FFmpegContent> c = _content.lock ();
144         if (!c) {
145                 return;
146         }
147         
148         vector<FFmpegSubtitleStream> a = c->subtitle_streams ();
149         vector<FFmpegSubtitleStream>::iterator i = a.begin ();
150         string const s = string_client_data (_subtitle_stream->GetClientObject (_subtitle_stream->GetSelection ()));
151         while (i != a.end() && lexical_cast<string> (i->id) != s) {
152                 ++i;
153         }
154
155         if (i != a.end ()) {
156                 c->set_subtitle_stream (*i);
157         }
158 }
159
160 void
161 FFmpegContentDialog::audio_mapping_changed (AudioMapping m)
162 {
163         shared_ptr<FFmpegContent> content = _content.lock ();
164
165         if (!content || !content->audio_stream()) {
166                 return;
167         }
168
169         /* XXX: set mapping in playlist */
170 }
171