- shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
- if (fc) {
- shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio));
-
- fd->Video.connect (bind (&Player::process_video, this, weak_ptr<Piece> (piece), _1, _2, _3, _4, _5, 0));
- fd->Audio.connect (bind (&Player::process_audio, this, weak_ptr<Piece> (piece), _1, _2, false));
- fd->Subtitle.connect (bind (&Player::process_subtitle, this, weak_ptr<Piece> (piece), _1, _2, _3, _4));
-
- fd->seek (fc->time_to_content_video_frames (fc->trim_start ()), true);
- piece->decoder = fd;
- }
-
- shared_ptr<const ImageContent> ic = dynamic_pointer_cast<const ImageContent> (*i);
- if (ic) {
- bool reusing = false;
-
- /* See if we can re-use an old ImageDecoder */
- for (list<shared_ptr<Piece> >::const_iterator j = old_pieces.begin(); j != old_pieces.end(); ++j) {
- shared_ptr<ImageDecoder> imd = dynamic_pointer_cast<ImageDecoder> ((*j)->decoder);
- if (imd && imd->content() == ic) {
- piece = *j;
- reusing = true;
+ /* Audio from this piece's decoder stream (which might be more or less than what we asked for) */
+ ContentAudio all = decoder->get_audio (j, content_frame, request_frames, accurate);
+
+ /* Gain */
+ if (content->audio_gain() != 0) {
+ shared_ptr<AudioBuffers> gain (new AudioBuffers (all.audio));
+ gain->apply_gain (content->audio_gain ());
+ all.audio = gain;
+ }
+
+ /* Remap channels */
+ shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->audio_channels(), all.audio->frames()));
+ dcp_mapped->make_silent ();
+ AudioMapping map = j->mapping ();
+ for (int i = 0; i < map.input_channels(); ++i) {
+ for (int j = 0; j < _film->audio_channels(); ++j) {
+ if (map.get (i, j) > 0) {
+ dcp_mapped->accumulate_channel (
+ all.audio.get(),
+ i,
+ j,
+ map.get (i, j)
+ );
+ }