#include <dcp/subtitle_string.h>
#include <sub/ssa_reader.h>
#include <sub/subtitle.h>
#include <dcp/subtitle_string.h>
#include <sub/ssa_reader.h>
#include <sub/subtitle.h>
if (video) {
double const vfr = _ffmpeg_content->video_frame_rate().get();
Frame const f = full_length.frames_round (vfr);
if (video) {
double const vfr = _ffmpeg_content->video_frame_rate().get();
Frame const f = full_length.frames_round (vfr);
ContentTime a = audio->stream_position(film(), i);
/* Unfortunately if a is 0 that really means that we don't know the stream position since
there has been no data on it since the last seek. In this case we'll just do nothing
ContentTime a = audio->stream_position(film(), i);
/* Unfortunately if a is 0 that really means that we don't know the stream position since
there has been no data on it since the last seek. In this case we'll just do nothing
ContentTime to_do = min (full_length - a, ContentTime::from_seconds (0.1));
shared_ptr<AudioBuffers> silence (new AudioBuffers (i->channels(), to_do.frames_ceil (i->frame_rate())));
silence->make_silent ();
ContentTime to_do = min (full_length - a, ContentTime::from_seconds (0.1));
shared_ptr<AudioBuffers> silence (new AudioBuffers (i->channels(), to_do.frames_ceil (i->frame_rate())));
silence->make_silent ();
- audio->emit (film(), i, silence, a);
+ audio->emit (film(), i, silence, a, true);
int r = av_read_frame (_format_context, &_packet);
/* AVERROR_INVALIDDATA can apparently be returned sometimes even when av_read_frame
int r = av_read_frame (_format_context, &_packet);
/* AVERROR_INVALIDDATA can apparently be returned sometimes even when av_read_frame
int const size = av_samples_get_buffer_size (
0, stream->stream(_format_context)->codec->channels, _frame->nb_samples, audio_sample_format (stream), 1
);
int const size = av_samples_get_buffer_size (
0, stream->stream(_format_context)->codec->channels, _frame->nb_samples, audio_sample_format (stream), 1
);
/* Sometimes there aren't as many channels in the _frame as in the stream */
for (int i = 0; i < _frame->channels; ++i) {
memcpy (data[i], p[i], frames * sizeof(float));
/* Sometimes there aren't as many channels in the _frame as in the stream */
for (int i = 0; i < _frame->channels; ++i) {
memcpy (data[i], p[i], frames * sizeof(float));
shared_ptr<FFmpegAudioStream> s = dynamic_pointer_cast<FFmpegAudioStream> (_ffmpeg_content->audio->stream ());
if (s) {
stream = s->index (_format_context);
shared_ptr<FFmpegAudioStream> s = dynamic_pointer_cast<FFmpegAudioStream> (_ffmpeg_content->audio->stream ());
if (s) {
stream = s->index (_format_context);
if (subtitle_codec_context ()) {
avcodec_flush_buffers (subtitle_codec_context ());
}
_have_current_subtitle = false;
if (subtitle_codec_context ()) {
avcodec_flush_buffers (subtitle_codec_context ());
}
_have_current_subtitle = false;
/* In some streams we see not every frame coming through with a timestamp; for those
that have AV_NOPTS_VALUE we need to work out the timestamp ourselves. This is
particularly noticeable with TrueHD streams (see #1111).
*/
/* In some streams we see not every frame coming through with a timestamp; for those
that have AV_NOPTS_VALUE we need to work out the timestamp ourselves. This is
particularly noticeable with TrueHD streams (see #1111).
*/
/* Give this data provided there is some, and its time is sane */
if (ct >= ContentTime() && data->frames() > 0) {
/* Give this data provided there is some, and its time is sane */
if (ct >= ContentTime() && data->frames() > 0) {
if (avcodec_decode_video2 (video_codec_context(), _frame, &frame_finished, &_packet) < 0 || !frame_finished) {
return false;
}
if (avcodec_decode_video2 (video_codec_context(), _frame, &frame_finished, &_packet) < 0 || !frame_finished) {
return false;
}
#ifdef DCPOMATIC_HAVE_AVSUBTITLERECT_PICT
/* Start of the first line in the subtitle */
uint8_t* sub_p = rect->pict.data[0];
#ifdef DCPOMATIC_HAVE_AVSUBTITLERECT_PICT
/* Start of the first line in the subtitle */
uint8_t* sub_p = rect->pict.data[0];
(i.e. first byte B, second G, third R, fourth A)
*/
(i.e. first byte B, second G, third R, fourth A)
*/
- /* sub_p looks up into a BGRA palette which is here
- (i.e. first byte B, second G, third R, fourth A)
+ /* sub_p looks up into a BGRA palette which is at rect->data[1].
+ (first byte B, second G, third R, fourth A)
#endif
/* And the stream has a map of those palette colours to colours
chosen by the user; created a `mapped' palette from those settings.
#endif
/* And the stream has a map of those palette colours to colours
chosen by the user; created a `mapped' palette from those settings.
map<RGBA, RGBA> colour_map = ffmpeg_content()->subtitle_stream()->colours ();
vector<RGBA> mapped_palette (rect->nb_colors);
for (int i = 0; i < rect->nb_colors; ++i) {
map<RGBA, RGBA> colour_map = ffmpeg_content()->subtitle_stream()->colours ();
vector<RGBA> mapped_palette (rect->nb_colors);
for (int i = 0; i < rect->nb_colors; ++i) {
- RGBA c ((palette[i] & 0xff0000) >> 16, (palette[i] & 0xff00) >> 8, palette[i] & 0xff, (palette[i] & 0xff000000) >> 24);
+ RGBA c (palette[2], palette[1], palette[0], palette[3]);
map<RGBA, RGBA>::const_iterator j = colour_map.find (c);
if (j != colour_map.end ()) {
mapped_palette[i] = j->second;
map<RGBA, RGBA>::const_iterator j = colour_map.find (c);
if (j != colour_map.end ()) {
mapped_palette[i] = j->second;
}
#ifdef DCPOMATIC_HAVE_AVSUBTITLERECT_PICT
sub_p += rect->pict.linesize[0];
#else
sub_p += rect->linesize[0];
#endif
}
#ifdef DCPOMATIC_HAVE_AVSUBTITLERECT_PICT
sub_p += rect->pict.linesize[0];
#else
sub_p += rect->linesize[0];
#endif