From f42d8091f37a2b3e01aa28993fc661c5f9eb0a7e Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Tue, 28 Feb 2012 22:25:40 +0000 Subject: Made demux_ts send pts not dts even for reordered (b-framed) video. This fixes a very old bug causing more or less unpredictable a/v lag. --HG-- extra : rebase_source : 094ca332b98500f3c10bec492c0003c83ff3152d --- src/demuxers/demux_qt.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index d0fa3fd77..e0455678b 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -83,6 +83,7 @@ typedef unsigned int qt_atom; #define STSC_ATOM QT_ATOM('s', 't', 's', 'c') #define STCO_ATOM QT_ATOM('s', 't', 'c', 'o') #define STTS_ATOM QT_ATOM('s', 't', 't', 's') +#define CTTS_ATOM QT_ATOM('c', 't', 't', 's') #define STSS_ATOM QT_ATOM('s', 't', 's', 's') #define CO64_ATOM QT_ATOM('c', 'o', '6', '4') @@ -165,6 +166,11 @@ typedef enum { typedef struct { int64_t offset; unsigned int size; + /* pts actually is dts for reordered video. Edit list and frame + duration code relies on that, so keep the offset separately + until sending to video fifo. + Value is small enough for plain int. */ + int ptsoffs; int64_t pts; int keyframe; unsigned int media_id; @@ -301,6 +307,10 @@ typedef struct { unsigned int time_to_sample_count; time_to_sample_table_t *time_to_sample_table; + /* pts to dts timeoffset to sample table */ + unsigned int timeoffs_to_sample_count; + time_to_sample_table_t *timeoffs_to_sample_table; + } qt_trak; typedef struct { @@ -640,6 +650,7 @@ static void free_qt_info(qt_info *info) { free(info->traks[i].sync_sample_table); free(info->traks[i].sample_to_chunk_table); free(info->traks[i].time_to_sample_table); + free(info->traks[i].timeoffs_to_sample_table); free(info->traks[i].decoder_config); for (j = 0; j < info->traks[i].stsd_atoms_count; j++) { if (info->traks[i].type == MEDIA_AUDIO) { @@ -981,6 +992,8 @@ static qt_error parse_trak_atom (qt_trak *trak, trak->sample_to_chunk_table = NULL; trak->time_to_sample_count = 0; trak->time_to_sample_table = NULL; + trak->timeoffs_to_sample_count = 0; + trak->timeoffs_to_sample_table = NULL; trak->frames = NULL; trak->frame_count = 0; trak->current_frame = 0; @@ -1685,6 +1698,47 @@ static qt_error parse_trak_atom (qt_trak *trak, trak->time_to_sample_table[j].duration); } trak->time_to_sample_table[j].count = 0; /* terminate with zero */ + + } else if (current_atom == CTTS_ATOM) { + + /* TJ. this has the same format as stts. If present, duration here + means (pts - dts), while the corresponding stts defines dts. */ + + /* there should only be one of these atoms */ + if (trak->timeoffs_to_sample_table + || current_atom_size < 12 || current_atom_size >= UINT_MAX) { + last_error = QT_HEADER_TROUBLE; + goto free_trak; + } + + trak->timeoffs_to_sample_count = _X_BE_32(&trak_atom[i + 8]); + + debug_atom_load(" qt ctts atom (timeoffset-to-sample atom): %d entries\n", + trak->timeoffs_to_sample_count); + + if (trak->timeoffs_to_sample_count > (current_atom_size - 12) / 8) { + last_error = QT_HEADER_TROUBLE; + goto free_trak; + } + + trak->timeoffs_to_sample_table = (time_to_sample_table_t *)calloc( + trak->timeoffs_to_sample_count+1, sizeof(time_to_sample_table_t)); + if (!trak->timeoffs_to_sample_table) { + last_error = QT_NO_MEMORY; + goto free_trak; + } + + /* load the pts to dts time offset to sample table */ + for (j = 0; j < trak->timeoffs_to_sample_count; j++) { + trak->timeoffs_to_sample_table[j].count = + _X_BE_32(&trak_atom[i + 12 + j * 8 + 0]); + trak->timeoffs_to_sample_table[j].duration = + _X_BE_32(&trak_atom[i + 12 + j * 8 + 4]); + debug_atom_load(" %d: count = %d, duration = %d\n", + j, trak->timeoffs_to_sample_table[j].count, + trak->timeoffs_to_sample_table[j].duration); + } + trak->timeoffs_to_sample_table[j].count = 0; /* terminate with zero */ } } @@ -1700,6 +1754,7 @@ free_trak: free(trak->sync_sample_table); free(trak->sample_to_chunk_table); free(trak->time_to_sample_table); + free(trak->timeoffs_to_sample_table); free(trak->decoder_config); if (trak->stsd_atoms) { for (i = 0; i < trak->stsd_atoms_count; i++) @@ -1853,6 +1908,8 @@ static qt_error build_frame_table(qt_trak *trak, int64_t current_pts; unsigned int pts_index; unsigned int pts_index_countdown; + unsigned int ptsoffs_index; + unsigned int ptsoffs_index_countdown; unsigned int audio_frame_counter = 0; unsigned int edit_list_media_time; int64_t edit_list_duration; @@ -1887,6 +1944,10 @@ static qt_error build_frame_table(qt_trak *trak, pts_index = 0; pts_index_countdown = trak->time_to_sample_table[pts_index].count; + /* used by reordered video */ + ptsoffs_index = 0; + ptsoffs_index_countdown = trak->timeoffs_to_sample_count ? + trak->timeoffs_to_sample_table[ptsoffs_index].count : 0; media_id_counts = calloc(trak->stsd_atoms_count, sizeof(int)); if (!media_id_counts) @@ -1957,6 +2018,21 @@ static qt_error build_frame_table(qt_trak *trak, trak->time_to_sample_table[pts_index].count; } + /* offset pts for reordered video */ + if (ptsoffs_index < trak->timeoffs_to_sample_count) { + trak->frames[frame_counter].ptsoffs = 90000 * + trak->timeoffs_to_sample_table[ptsoffs_index].duration / + trak->timescale; + ptsoffs_index_countdown--; + /* time to refresh countdown? */ + if (!ptsoffs_index_countdown) { + ptsoffs_index++; + ptsoffs_index_countdown = + trak->timeoffs_to_sample_table[ptsoffs_index].count; + } + } else + trak->frames[frame_counter].ptsoffs = 0; + samples_per_chunk--; frame_counter++; } @@ -2051,6 +2127,7 @@ static qt_error build_frame_table(qt_trak *trak, trak->frames[j].pts = audio_frame_counter; trak->frames[j].pts *= 90000; trak->frames[j].pts /= trak->timescale; + trak->frames[j].ptsoffs = 0; /* fetch the alleged chunk size according to the QT header */ trak->frames[j].size = @@ -2592,7 +2669,7 @@ static int demux_qt_send_chunk(demux_plugin_t *this_gen) { buf->extra_info->input_normpos = (int)( (double) (video_trak->frames[i].offset - this->data_start) * 65535 / this->data_size); buf->extra_info->input_time = video_trak->frames[i].pts / 90; - buf->pts = video_trak->frames[i].pts; + buf->pts = video_trak->frames[i].pts + (int64_t)video_trak->frames[i].ptsoffs; buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = frame_duration; -- cgit v1.2.3 From cc27f8ffa02c70fd8a168a23b5494575adc9c881 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Thu, 12 Apr 2012 21:04:30 +0300 Subject: Use proper device paths for the Blu-ray and VCD input plugins on OpenBSD --- src/input/input_bluray.c | 13 +++++++++++-- src/input/input_vcd.c | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/input/input_bluray.c b/src/input/input_bluray.c index a05307a4f..c9152545e 100644 --- a/src/input/input_bluray.c +++ b/src/input/input_bluray.c @@ -74,6 +74,15 @@ #define MIN_TITLE_LENGTH 180 +#define BLURAY_MNT_PATH "/mnt/bluray" +#if defined(__sun) +#define BLURAY_PATH "/vol/dev/aliases/cdrom0" +#elif defined(__OpenBSD__) +#define BLURAY_PATH "/dev/rcd0c" +#else +#define BLURAY_PATH "/dev/dvd" +#endif + /* */ typedef struct { @@ -1644,13 +1653,13 @@ static void *bluray_init_plugin (xine_t *xine, void *data) this->mountpoint = config->register_filename(config, "media.bluray.mountpoint", - "/mnt/bluray", XINE_CONFIG_STRING_IS_DIRECTORY_NAME, + BLURAY_MNT_PATH, XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("BluRay mount point"), _("Default mount location for BluRay discs."), 0, mountpoint_change_cb, (void *) this); this->device = config->register_filename(config, "media.bluray.device", - "/dev/dvd", XINE_CONFIG_STRING_IS_DIRECTORY_NAME, + BLURAY_PATH, XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("device used for BluRay playback"), _("The path to the device " "which you intend to use for playing BluRy discs."), diff --git a/src/input/input_vcd.c b/src/input/input_vcd.c index 3f31c7c9d..8b1a0fcee 100644 --- a/src/input/input_vcd.c +++ b/src/input/input_vcd.c @@ -53,6 +53,8 @@ #if defined(__sun) #define CDROM "/vol/dev/aliases/cdrom0" +#elif defined(__OpenBSD__) +#define CDROM "/dev/rcd0c" #else /* for FreeBSD make a link to the right devnode, like /dev/acd0c */ #define CDROM "/dev/cdrom" -- cgit v1.2.3 From 93e8da81f50c7c3d5c5d24fb997ec8ff067084dd Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Wed, 21 Dec 2011 21:23:21 +0100 Subject: Fix multithreaded initialization with API change thread count needs to be set before avcodec_open otherwise it will be stuck with a single thread at least for h264 (might also want to use avcodec_open2 instead?) --- src/combined/ffmpeg/ff_video_decoder.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index 2ec18c55f..379732a82 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -329,6 +329,13 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) if (this->class->choose_speed_over_accuracy) this->context->flags2 |= CODEC_FLAG2_FAST; +#ifdef DEPRECATED_AVCODEC_THREAD_INIT + if (this->class->thread_count > 1) { + if (this->codec->id != CODEC_ID_SVQ3) + this->context->thread_count = this->class->thread_count; + } +#endif + pthread_mutex_lock(&ffmpeg_lock); if (avcodec_open (this->context, this->codec) < 0) { pthread_mutex_unlock(&ffmpeg_lock); @@ -356,14 +363,13 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) } } +#ifndef DEPRECATED_AVCODEC_THREAD_INIT if (this->class->thread_count > 1) { if (this->codec->id != CODEC_ID_SVQ3 -#ifndef DEPRECATED_AVCODEC_THREAD_INIT - && avcodec_thread_init(this->context, this->class->thread_count) != -1 -#endif - ) + && avcodec_thread_init(this->context, this->class->thread_count) != -1) this->context->thread_count = this->class->thread_count; } +#endif this->context->skip_loop_filter = skip_loop_filter_enum_values[this->class->skip_loop_filter_enum]; -- cgit v1.2.3 From ee7f8b278836b0fca2a07b9a413dd25d7e10c88e Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Thu, 19 Apr 2012 09:26:04 +0300 Subject: Fixed decoding of full range YUV420 H.264 videos (segfault). Might still need color space conversion ... --- src/combined/ffmpeg/ff_video_decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index 379732a82..a1ad1cbde 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -828,7 +828,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { du += img->pitches[1]; dv += img->pitches[2]; - if (this->context->pix_fmt != PIX_FMT_YUV420P) { + if (this->context->pix_fmt != PIX_FMT_YUV420P && this->context->pix_fmt != PIX_FMT_YUVJ420P) { su += 2*this->av_frame->linesize[1]; sv += 2*this->av_frame->linesize[2]; } else { -- cgit v1.2.3 From f75e0c5efc1fcedf4312acedd4e36fd7f5314127 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Thu, 26 Apr 2012 13:58:54 +0300 Subject: Check read() return value --- src/input/input_dvb.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index 9077c221b..3ed2eea7f 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -1469,9 +1469,17 @@ static void load_epg_data(dvb_input_plugin_t *this) return; } n = read(this->tuner->fd_pidfilter[EITFILTER], eit, 3); + if (n != 3) { + xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"Error reading EPG section length\n"); + break; + } table_id = getbits(eit, 0, 8); section_len = (unsigned int)getbits(eit, 12, 12); n = read(this->tuner->fd_pidfilter[EITFILTER], eit + 3, section_len); + if (n != section_len) { + xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"Error reading EPG section data\n"); + break; + } service_id = (unsigned int)getbits(eit, 24, 16); -- cgit v1.2.3 From 946f58f160b0c3004ac49be5dd9c71822387af9e Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Thu, 26 Apr 2012 14:14:37 +0300 Subject: Fixed demux_qt for the pts < dts case --- src/demuxers/demux_qt.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index e0455678b..7ef850028 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -2020,9 +2020,11 @@ static qt_error build_frame_table(qt_trak *trak, /* offset pts for reordered video */ if (ptsoffs_index < trak->timeoffs_to_sample_count) { - trak->frames[frame_counter].ptsoffs = 90000 * - trak->timeoffs_to_sample_table[ptsoffs_index].duration / - trak->timescale; + /* TJ. this is 32 bit signed. All casts necessary for my gcc 4.5.0 */ + int i = trak->timeoffs_to_sample_table[ptsoffs_index].duration; + if ((sizeof (int) > 4) && (i & 0x80000000)) + i |= ~0xffffffffL; + trak->frames[frame_counter].ptsoffs = (int)90000 * i / (int)trak->timescale; ptsoffs_index_countdown--; /* time to refresh countdown? */ if (!ptsoffs_index_countdown) { -- cgit v1.2.3