Update to Xine-lib 1.2.5.

ok juanfra@
This commit is contained in:
brad 2014-04-16 05:09:00 +00:00
parent 08da790645
commit 5ec30566a2
9 changed files with 16 additions and 1069 deletions

View File

@ -1,16 +1,15 @@
# $OpenBSD: Makefile,v 1.108 2014/01/08 00:17:53 brad Exp $
# $OpenBSD: Makefile,v 1.109 2014/04/16 05:09:00 brad Exp $
SHARED_ONLY= Yes
COMMENT= multimedia decoding library
DISTNAME= xine-lib-1.2.4
REVISION= 0
DISTNAME= xine-lib-1.2.5
CATEGORIES= multimedia
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE:=xine/}
EXTRACT_SUFX= .tar.xz
SHARED_LIBS= xine 30.2
SHARED_LIBS= xine 31.0
HOMEPAGE= http://www.xine-project.org/
@ -21,12 +20,12 @@ PERMIT_PACKAGE_CDROM= patents
PERMIT_PACKAGE_FTP= Yes
WANTLIB= FLAC GL GLU ICE SDL SM X11 Xext Xinerama Xv XvMCW a52 avcodec \
avutil bluray c cdio dca dvdnav dvdread expat faad fontconfig \
freetype iso9660 jpeg m mad modplug mpcdec mng ogg postproc \
pthread pthread-stubs sndio speex theora usbhid vcdinfo vorbis \
wavpack xcb-shape xcb-shm xcb-xv xcb xdg-basedir xml2 z
avformat avutil bluray c cdio dca dvdnav dvdread expat faad \
fontconfig freetype iso9660 jpeg m mad modplug mpcdec mng ogg \
postproc pthread pthread-stubs sndio speex theora usbhid vcdinfo \
vorbis wavpack xcb-shape xcb-shm xcb-xv xcb xdg-basedir xml2 z
XINEAPI_REV= 2.3
XINEAPI_REV= 2.4
SUBST_VARS+= XINEAPI_REV
MODULES= devel/gettext
@ -43,7 +42,7 @@ LIB_DEPENDS= audio/faad \
audio/speex \
audio/wavpack \
devel/sdl \
graphics/ffmpeg>=20111126 \
graphics/ffmpeg>=20130319 \
graphics/jpeg \
graphics/libmng \
graphics/vcdimager \
@ -69,6 +68,7 @@ CONFIGURE_ARGS+=--disable-aalib \
--disable-optimizations \
--disable-real-codecs \
--disable-samba \
--disable-vpx \
--disable-w32dll \
--with-external-dvdnav \
--with-fontconfig \

View File

@ -1,2 +1,2 @@
SHA256 (xine-lib-1.2.4.tar.xz) = nFsbTve9BZGWLDIqOvpwnuqluuZkZ4VI8TQOZPQ6u90=
SIZE (xine-lib-1.2.4.tar.xz) = 4954992
SHA256 (xine-lib-1.2.5.tar.xz) = yOpAkNH6g/i2iHEYcwVHqpGIYtYPQ+pnAIn5BT5Uq3w=
SIZE (xine-lib-1.2.5.tar.xz) = 5007012

View File

@ -1,15 +0,0 @@
$OpenBSD: patch-src_combined_ffmpeg_Makefile_in,v 1.3 2013/11/30 22:13:37 brad Exp $
Improve locating of avcodec.h by replacing the sed scripts.
--- src/combined/ffmpeg/Makefile.in.orig Wed Nov 20 18:40:06 2013
+++ src/combined/ffmpeg/Makefile.in Wed Nov 20 18:40:47 2013
@@ -998,7 +998,7 @@ avcodec_video.list: AV_CODECS:=/CODEC_ID_MPEG1VIDEO/,/
# that weird shell call just yields full path of the avcodec.h file
avcodec_audio.list avcodec_video.list: $(shell \
echo '#include "$(srcdir)/ffmpeg_decoder.h"' | $(AV_CPP) -M - |\
- sed -e 's/ \+/\n/g;' | sed -n -e '/avcodec\.h/p;')
+ sed -e '/avcodec\.h/! d; s%^.* \([^ ]*/avcodec\.h\) .*%\1%')
$(AM_V_GEN)echo '#include "$(srcdir)/ffmpeg_decoder.h"' | $(AV_CPP) - |\
sed -e $(AV_CODECS)'! d; s/^[ \t]*//; s/[=,].*//; /^$$/ d' >$@

View File

@ -1,39 +0,0 @@
$OpenBSD: patch-src_demuxers_demux_flv_c,v 1.4 2013/11/30 22:13:37 brad Exp $
Add audio language info.
--- src/demuxers/demux_flv.c.orig Wed Nov 20 21:13:27 2013
+++ src/demuxers/demux_flv.c Wed Nov 20 21:13:39 2013
@@ -1034,11 +1034,31 @@ static int demux_flv_get_stream_length (demux_plugin_t
}
static uint32_t demux_flv_get_capabilities(demux_plugin_t *this_gen) {
- return DEMUX_CAP_NOCAP;
+ return DEMUX_CAP_AUDIOLANG;
}
static int demux_flv_get_optional_data(demux_plugin_t *this_gen,
void *data, int data_type) {
+ demux_flv_t *this = (demux_flv_t *) this_gen;
+
+ /* be a bit paranoid */
+ if (this == NULL || this->stream == NULL)
+ return DEMUX_OPTIONAL_UNSUPPORTED;
+
+ switch (data_type) {
+ case DEMUX_OPTIONAL_DATA_AUDIOLANG: {
+ char *str = data;
+ int channel = *((int *)data);
+ if (channel != 0) {
+ strcpy (str, "none");
+ } else {
+ strcpy (str, "und");
+ return DEMUX_OPTIONAL_SUCCESS;
+ }
+ }
+ break;
+ default: ;
+ }
return DEMUX_OPTIONAL_UNSUPPORTED;
}

View File

@ -1,690 +0,0 @@
$OpenBSD: patch-src_demuxers_demux_qt_c,v 1.19 2013/11/30 22:13:37 brad Exp $
- Simple (E)AC3 support.
- Add multitrak audio support.
- Add audio language info.
--- src/demuxers/demux_qt.c.orig Wed Sep 18 06:04:54 2013
+++ src/demuxers/demux_qt.c Wed Nov 20 21:11:34 2013
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001-2012 the xine project
+ * Copyright (C) 2001-2013 the xine project
*
* This file is part of xine, a free video player.
*
@@ -108,6 +108,8 @@ typedef unsigned int qt_atom;
#define IN24_FOURCC ME_FOURCC('i', 'n', '2', '4')
#define NI42_FOURCC ME_FOURCC('4', '2', 'n', 'i')
#define AVC1_FOURCC ME_FOURCC('a', 'v', 'c', '1')
+#define AC_3_FOURCC ME_FOURCC('a', 'c', '-', '3')
+#define EAC3_FOURCC ME_FOURCC('e', 'c', '-', '3')
#define UDTA_ATOM QT_ATOM('u', 'd', 't', 'a')
#define META_ATOM QT_ATOM('m', 'e', 't', 'a')
@@ -131,8 +133,9 @@ typedef unsigned int qt_atom;
#define RMVC_ATOM QT_ATOM('r', 'm', 'v', 'c')
#define QTIM_ATOM QT_ATOM('q', 't', 'i', 'm')
-/* placeholder for cutting and pasting */
+/* placeholder for cutting and pasting
#define _ATOM QT_ATOM('', '', '', '')
+*/
#define ATOM_PREAMBLE_SIZE 8
#define PALETTE_COUNT 256
@@ -315,6 +318,11 @@ typedef struct {
unsigned int timeoffs_to_sample_count;
time_to_sample_table_t *timeoffs_to_sample_table;
+ /* what to add to output buffer type */
+ int audio_index;
+
+ int lang;
+
} qt_trak;
typedef struct {
@@ -330,6 +338,10 @@ typedef struct {
int trak_count;
qt_trak *traks;
+#define MAX_AUDIO_TRAKS 8
+ int audio_trak_count;
+ int audio_traks[MAX_AUDIO_TRAKS];
+
/* the trak numbers that won their respective frame count competitions */
int video_trak;
int audio_trak;
@@ -699,13 +711,12 @@ static int is_qt_file(input_plugin_t *qt_file) {
off_t moov_atom_offset = -1;
int64_t moov_atom_size = -1;
int i;
- int len;
/* if the input is non-seekable, be much more stringent about qualifying
* a QT file: In this case, the moov must be the first atom in the file */
if ((qt_file->get_capabilities(qt_file) & INPUT_CAP_SEEKABLE) == 0) {
unsigned char preview[MAX_PREVIEW_SIZE] = { 0, };
- len = qt_file->get_optional_data(qt_file, preview, INPUT_OPTIONAL_DATA_PREVIEW);
+ qt_file->get_optional_data(qt_file, preview, INPUT_OPTIONAL_DATA_PREVIEW);
if (_X_BE_32(&preview[4]) == MOOV_ATOM)
return 1;
else {
@@ -798,7 +809,7 @@ static void parse_meta_atom(qt_info *info, unsigned ch
const uint8_t *const current_atom = &meta_atom[i];
const qt_atom current_atom_code = _X_BE_32(&current_atom[4]);
const uint32_t current_atom_size = _X_BE_32(&current_atom[0]);
- uint32_t handler_type = 0;
+ /*uint32_t handler_type = 0;*/
switch (current_atom_code) {
case HDLR_ATOM: {
@@ -813,7 +824,7 @@ static void parse_meta_atom(qt_info *info, unsigned ch
return;
}
- handler_type = _X_BE_32(&current_atom[12]);
+ /*handler_type = _X_BE_32(&current_atom[12]);*/
}
break;
@@ -1005,6 +1016,7 @@ static qt_error parse_trak_atom (qt_trak *trak,
if ( version > 1 ) continue; /* unsupported, undocumented */
trak->timescale = _X_BE_32(&trak_atom[i + (version == 0 ? 0x10 : 0x18) ]);
+ trak->lang = _X_BE_16 (trak_atom + i + (version == 0 ? 0x18 : 0x24));
}
break;
@@ -1284,6 +1296,8 @@ static qt_error parse_trak_atom (qt_trak *trak,
* further, do not do load these parameters if the audio is just
* PCM ('raw ', 'twos', 'sowt' or 'in24') */
if ((current_stsd_atom_size > 0x24) &&
+ (trak->stsd_atoms[k].audio.codec_fourcc != AC_3_FOURCC) &&
+ (trak->stsd_atoms[k].audio.codec_fourcc != EAC3_FOURCC) &&
(trak->stsd_atoms[k].audio.codec_fourcc != TWOS_FOURCC) &&
(trak->stsd_atoms[k].audio.codec_fourcc != SOWT_FOURCC) &&
(trak->stsd_atoms[k].audio.codec_fourcc != RAW_FOURCC) &&
@@ -1322,6 +1336,12 @@ static qt_error parse_trak_atom (qt_trak *trak,
if (trak->stsd_atoms[k].audio.codec_fourcc == SAMR_FOURCC)
trak->stsd_atoms[k].audio.vbr = 1;
+ if (trak->stsd_atoms[k].audio.codec_fourcc == AC_3_FOURCC)
+ trak->stsd_atoms[k].audio.vbr = 1;
+
+ if (trak->stsd_atoms[k].audio.codec_fourcc == EAC3_FOURCC)
+ trak->stsd_atoms[k].audio.vbr = 1;
+
if (trak->stsd_atoms[k].audio.codec_fourcc == ALAC_FOURCC) {
trak->stsd_atoms[k].audio.vbr = 1;
/* further, FFmpeg's ALAC decoder requires 36 out-of-band bytes */
@@ -2446,10 +2466,8 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge
unsigned int frame_aligned_buf_size;
int frame_duration;
int first_buf;
- qt_trak *video_trak = NULL;
- qt_trak *audio_trak = NULL;
- int dispatch_audio; /* boolean for deciding which trak to dispatch */
- int64_t pts_diff;
+ qt_trak *trak = NULL;
+ off_t current_pos = this->input->get_current_pos (this->input);
/* if this is DRM-protected content, finish playback before it even
* tries to start */
@@ -2468,117 +2486,105 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge
return this->status;
}
- if (this->qt->video_trak != -1) {
- video_trak = &this->qt->traks[this->qt->video_trak];
- }
- if (this->qt->audio_trak != -1) {
- audio_trak = &this->qt->traks[this->qt->audio_trak];
- }
-
- if (!audio_trak && !video_trak) {
- /* something is really wrong if this case is reached */
- this->status = DEMUX_FINISHED;
- return this->status;
- }
-
- /* check if it is time to seek */
- if (this->qt->seek_flag) {
- this->qt->seek_flag = 0;
-
- /* if audio is present, send pts of current audio frame, otherwise
- * send current video frame pts */
- if (audio_trak)
- _x_demux_control_newpts(this->stream,
- audio_trak->frames[audio_trak->current_frame].pts,
- BUF_FLAG_SEEK);
- else
- _x_demux_control_newpts(this->stream,
- video_trak->frames[video_trak->current_frame].pts,
- BUF_FLAG_SEEK);
- }
-
/* Decide the trak from which to dispatch a frame. Policy: Dispatch
* the frames in offset order as much as possible. If the pts difference
* between the current frames from the audio and video traks is too
* wide, make an exception. This exception deals with non-interleaved
* Quicktime files. */
- if (!audio_trak) {
+ do {
+ int traks[MAX_AUDIO_TRAKS + 1];
+ int trak_count = 0;
+ int min_trak = -1, next_trak = -1;
+ int64_t min_pts = 0, max_pts = 0; /* avoid warning */
+ off_t next_pos = 0x7fffffffffffffffLL;
+ int i;
- /* only video is present */
- dispatch_audio = 0;
- if (video_trak->current_frame >= video_trak->frame_count) {
- this->status = DEMUX_FINISHED;
- return this->status;
+ /* Step 1: list yet unfinished traks. */
+ if (this->qt->video_trak >= 0) {
+ trak = &this->qt->traks[this->qt->video_trak];
+ if (trak->current_frame < trak->frame_count)
+ traks[trak_count++] = this->qt->video_trak;
}
+ for (i = 0; i < this->qt->audio_trak_count; i++) {
+ trak = &this->qt->traks[this->qt->audio_traks[i]];
+ if (trak->current_frame < trak->frame_count)
+ traks[trak_count++] = this->qt->audio_traks[i];
+ }
- } else if (!video_trak) {
-
- /* only audio is present */
- dispatch_audio = 1;
- if (audio_trak->current_frame >= audio_trak->frame_count) {
+ /* Step 2: handle trivial cases. */
+ if (trak_count == 0) {
this->status = DEMUX_FINISHED;
return this->status;
}
+ if (trak_count == 1) {
+ trak = &this->qt->traks[traks[0]];
+ break;
+ }
- } else {
+ /* Step 3: find
+ * The minimum pts and the trak who has it.
+ * The maximum pts.
+ * The forward nearest to current position and the trak thereof. */
+ for (i = 0; i < trak_count; i++) {
+ int64_t pts;
+ off_t pos;
+ trak = &this->qt->traks[traks[i]];
+ pts = trak->frames[trak->current_frame].pts;
+ if (i == 0) {
+ min_pts = max_pts = pts;
+ min_trak = traks[i];
+ } else if (pts < min_pts) {
+ min_pts = pts;
+ min_trak = traks[i];
+ } else if (pts > max_pts)
+ max_pts = pts;
+ pos = trak->frames[trak->current_frame].offset;
+ if ((pos >= current_pos) && (pos < next_pos)) {
+ next_pos = pos;
+ next_trak = traks[i];
+ }
+ }
- /* both audio and video are present; start making some tough choices */
+ /* Step 4: after seek, or if the pts scissors opened too much, send minimum pts trak next.
+ Otherwise, take next one by offset. */
+ i = this->qt->seek_flag || (next_trak < 0) || (max_pts - min_pts > MAX_PTS_DIFF) ?
+ min_trak : next_trak;
+ trak = &this->qt->traks[i];
+ } while (0);
- /* check the frame count limits */
- if ((audio_trak->current_frame >= audio_trak->frame_count) &&
- (video_trak->current_frame >= video_trak->frame_count)) {
+ if (this->stream->xine->verbosity == XINE_VERBOSITY_DEBUG + 1) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1,
+ "demux_qt: sending trak %d dts %"PRId64" pos %"PRId64"\n",
+ trak - this->qt->traks,
+ trak->frames[trak->current_frame].pts,
+ trak->frames[trak->current_frame].offset);
+ }
- this->status = DEMUX_FINISHED;
- return this->status;
+ /* check if it is time to seek */
+ if (this->qt->seek_flag) {
+ this->qt->seek_flag = 0;
- } else if (video_trak->current_frame >= video_trak->frame_count) {
-
- dispatch_audio = 1;
-
- } else if (audio_trak->current_frame >= audio_trak->frame_count) {
-
- dispatch_audio = 0;
-
- } else {
-
- /* at this point, it is certain that both traks still have frames
- * yet to be dispatched */
- pts_diff = audio_trak->frames[audio_trak->current_frame].pts;
- pts_diff -= video_trak->frames[video_trak->current_frame].pts;
-
- if (pts_diff > MAX_PTS_DIFF) {
- /* if diff is +max_diff, audio is too far ahead of video */
- dispatch_audio = 0;
- } else if (pts_diff < -MAX_PTS_DIFF) {
- /* if diff is -max_diff, video is too far ahead of audio */
- dispatch_audio = 1;
- } else if (audio_trak->frames[audio_trak->current_frame].offset <
- video_trak->frames[video_trak->current_frame].offset) {
- /* pts diff is not too wide, decide based on earlier offset */
- dispatch_audio = 1;
- } else {
- dispatch_audio = 0;
- }
- }
+ /* send min pts of all used traks, usually audio (see demux_qt_seek ()). */
+ _x_demux_control_newpts (this->stream, trak->frames[trak->current_frame].pts, BUF_FLAG_SEEK);
}
- if (!dispatch_audio) {
- i = video_trak->current_frame++;
+ if (trak->type == MEDIA_VIDEO) {
+ i = trak->current_frame++;
- if (video_trak->frames[i].media_id != video_trak->properties->video.media_id) {
+ if (trak->frames[i].media_id != trak->properties->video.media_id) {
this->status = DEMUX_OK;
return this->status;
}
- remaining_sample_bytes = video_trak->frames[i].size;
- this->input->seek(this->input, video_trak->frames[i].offset,
- SEEK_SET);
+ remaining_sample_bytes = trak->frames[i].size;
+ if (trak->frames[i].offset != current_pos)
+ this->input->seek (this->input, trak->frames[i].offset, SEEK_SET);
- if (i + 1 < video_trak->frame_count) {
+ if (i + 1 < trak->frame_count) {
/* frame duration is the pts diff between this video frame and
* the next video frame */
- frame_duration = video_trak->frames[i + 1].pts;
- frame_duration -= video_trak->frames[i].pts;
+ frame_duration = trak->frames[i + 1].pts;
+ frame_duration -= trak->frames[i].pts;
} else {
/* give the last frame some fixed duration */
frame_duration = 12000;
@@ -2590,10 +2596,10 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge
* to compensate. */
if (!frame_duration) {
frame_duration = 1;
- video_trak->properties->video.edit_list_compensation++;
+ trak->properties->video.edit_list_compensation++;
} else {
- frame_duration -= video_trak->properties->video.edit_list_compensation;
- video_trak->properties->video.edit_list_compensation = 0;
+ frame_duration -= trak->properties->video.edit_list_compensation;
+ trak->properties->video.edit_list_compensation = 0;
}
_x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION,
@@ -2601,19 +2607,19 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge
debug_video_demux(" qt: sending off video frame %d from offset 0x%"PRIX64", %d bytes, media id %d, %"PRId64" pts\n",
i,
- video_trak->frames[i].offset,
- video_trak->frames[i].size,
- video_trak->frames[i].media_id,
- video_trak->frames[i].pts);
+ trak->frames[i].offset,
+ trak->frames[i].size,
+ trak->frames[i].media_id,
+ trak->frames[i].pts);
while (remaining_sample_bytes) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = video_trak->properties->video.codec_buftype;
+ buf->type = trak->properties->video.codec_buftype;
if( this->data_size )
- buf->extra_info->input_normpos = (int)( (double) (video_trak->frames[i].offset - this->data_start)
+ buf->extra_info->input_normpos = (int)( (double) (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 + (int64_t)video_trak->frames[i].ptsoffs;
+ buf->extra_info->input_time = trak->frames[i].pts / 90;
+ buf->pts = trak->frames[i].pts + (int64_t)trak->frames[i].ptsoffs;
buf->decoder_flags |= BUF_FLAG_FRAMERATE;
buf->decoder_info[0] = frame_duration;
@@ -2631,7 +2637,7 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge
break;
}
- if (video_trak->frames[i].keyframe)
+ if (trak->frames[i].keyframe)
buf->decoder_flags |= BUF_FLAG_KEYFRAME;
if (!remaining_sample_bytes)
buf->decoder_flags |= BUF_FLAG_FRAME_END;
@@ -2639,11 +2645,11 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge
this->video_fifo->put(this->video_fifo, buf);
}
- } else {
+ } else { /* trak->type == MEDIA_AUDIO */
/* load an audio sample and packetize it */
- i = audio_trak->current_frame++;
+ i = trak->current_frame++;
- if (audio_trak->frames[i].media_id != audio_trak->properties->audio.media_id) {
+ if (trak->frames[i].media_id != trak->properties->audio.media_id) {
this->status = DEMUX_OK;
return this->status;
}
@@ -2652,24 +2658,24 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge
if (!this->audio_fifo)
return this->status;
- remaining_sample_bytes = audio_trak->frames[i].size;
+ remaining_sample_bytes = trak->frames[i].size;
- this->input->seek(this->input, audio_trak->frames[i].offset,
- SEEK_SET);
+ if (trak->frames[i].offset != current_pos)
+ this->input->seek (this->input, trak->frames[i].offset, SEEK_SET);
debug_audio_demux(" qt: sending off audio frame %d from offset 0x%"PRIX64", %d bytes, media id %d, %"PRId64" pts\n",
i,
- audio_trak->frames[i].offset,
- audio_trak->frames[i].size,
- audio_trak->frames[i].media_id,
- audio_trak->frames[i].pts);
+ trak->frames[i].offset,
+ trak->frames[i].size,
+ trak->frames[i].media_id,
+ trak->frames[i].pts);
first_buf = 1;
while (remaining_sample_bytes) {
buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = audio_trak->properties->audio.codec_buftype;
+ buf->type = trak->properties->audio.codec_buftype;
if( this->data_size )
- buf->extra_info->input_normpos = (int)( (double) (audio_trak->frames[i].offset - this->data_start)
+ buf->extra_info->input_normpos = (int)( (double) (trak->frames[i].offset - this->data_start)
* 65535 / this->data_size);
/* The audio chunk is often broken up into multiple 8K buffers when
* it is sent to the audio decoder. Only attach the proper timestamp
@@ -2680,20 +2686,20 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge
if ((buf->type == BUF_AUDIO_LPCM_BE) ||
(buf->type == BUF_AUDIO_LPCM_LE)) {
if (first_buf) {
- buf->extra_info->input_time = audio_trak->frames[i].pts / 90;
- buf->pts = audio_trak->frames[i].pts;
+ buf->extra_info->input_time = trak->frames[i].pts / 90;
+ buf->pts = trak->frames[i].pts;
first_buf = 0;
} else {
buf->extra_info->input_time = 0;
buf->pts = 0;
}
} else {
- buf->extra_info->input_time = audio_trak->frames[i].pts / 90;
- buf->pts = audio_trak->frames[i].pts;
+ buf->extra_info->input_time = trak->frames[i].pts / 90;
+ buf->pts = trak->frames[i].pts;
}
/* 24-bit audio doesn't fit evenly into the default 8192-byte buffers */
- if (audio_trak->properties->audio.bits == 24)
+ if (trak->properties->audio.bits == 24)
frame_aligned_buf_size = 8184;
else
frame_aligned_buf_size = buf->max_size;
@@ -2713,9 +2719,9 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge
/* Special case alert: If this is signed, 8-bit data, transform
* the data to unsigned. */
- if ((audio_trak->properties->audio.bits == 8) &&
- ((audio_trak->properties->audio.codec_fourcc == TWOS_FOURCC) ||
- (audio_trak->properties->audio.codec_fourcc == SOWT_FOURCC)))
+ if ((trak->properties->audio.bits == 8) &&
+ ((trak->properties->audio.codec_fourcc == TWOS_FOURCC) ||
+ (trak->properties->audio.codec_fourcc == SOWT_FOURCC)))
for (j = 0; j < buf->size; j++)
buf->content[j] += 0x80;
@@ -2723,6 +2729,7 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge
buf->decoder_flags |= BUF_FLAG_FRAME_END;
}
+ buf->type |= trak->audio_index;
this->audio_fifo->put(this->audio_fifo, buf);
}
}
@@ -2738,6 +2745,9 @@ static void demux_qt_send_headers(demux_plugin_t *this
qt_trak *audio_trak = NULL;
unsigned int audio_bitrate;
+ int tnum;
+ int audio_index = 0;
+
/* for deciding data start and data size */
int64_t first_video_offset = -1;
int64_t last_video_offset = -1;
@@ -2820,31 +2830,6 @@ static void demux_qt_send_headers(demux_plugin_t *this
if (this->qt->audio_trak != -1) {
- /* in mp4 files the audio fourcc is always 'mp4a' - the codec is
- * specified by the object type id field in the esds atom */
- if(audio_trak->properties->audio.codec_fourcc == MP4A_FOURCC) {
- switch(audio_trak->object_type_id) {
- case 107:
- audio_trak->properties->audio.codec_buftype = BUF_AUDIO_MPEG;
- break;
- default:
- /* default to AAC if we have no better idea */
- audio_trak->properties->audio.codec_buftype = BUF_AUDIO_AAC;
- break;
- }
- } else {
- audio_trak->properties->audio.codec_buftype =
- _x_formattag_to_buf_audio(audio_trak->properties->audio.codec_fourcc);
- }
-
- if( !audio_trak->properties->audio.codec_buftype &&
- audio_trak->properties->audio.codec_fourcc )
- {
- audio_trak->properties->audio.codec_buftype = BUF_AUDIO_UNKNOWN;
- _x_report_audio_format_tag (this->stream->xine, LOG_MODULE,
- audio_trak->properties->audio.codec_fourcc);
- }
-
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS,
audio_trak->properties->audio.channels);
@@ -2941,10 +2926,44 @@ static void demux_qt_send_headers(demux_plugin_t *this
this->video_fifo->put (this->video_fifo, buf);
}
- if ((this->qt->audio_trak != -1) &&
- (audio_trak->properties->audio.codec_buftype) &&
- this->audio_fifo) {
+ for (tnum = 0; tnum < this->qt->trak_count; tnum++) {
+ audio_trak = &this->qt->traks[tnum];
+ if (audio_trak->type != MEDIA_AUDIO)
+ continue;
+
+ /* in mp4 files the audio fourcc is always 'mp4a' - the codec is
+ * specified by the object type id field in the esds atom */
+ if (audio_trak->properties->audio.codec_fourcc == MP4A_FOURCC) {
+ switch (audio_trak->object_type_id) {
+ case 107:
+ audio_trak->properties->audio.codec_buftype = BUF_AUDIO_MPEG;
+ break;
+ default:
+ /* default to AAC if we have no better idea */
+ audio_trak->properties->audio.codec_buftype = BUF_AUDIO_AAC;
+ break;
+ }
+ } else {
+ audio_trak->properties->audio.codec_buftype =
+ _x_formattag_to_buf_audio (audio_trak->properties->audio.codec_fourcc);
+ }
+
+ if (!audio_trak->properties->audio.codec_buftype &&
+ audio_trak->properties->audio.codec_fourcc) {
+ audio_trak->properties->audio.codec_buftype = BUF_AUDIO_UNKNOWN;
+ _x_report_audio_format_tag (this->stream->xine, LOG_MODULE,
+ audio_trak->properties->audio.codec_fourcc);
+ }
+
+ if ((audio_trak->properties->audio.codec_buftype == 0) ||
+ (audio_index >= MAX_AUDIO_TRAKS) ||
+ (this->audio_fifo == NULL))
+ continue;
+
+ this->qt->audio_traks[audio_index] = tnum;
+ audio_trak->audio_index = audio_index;
+
/* set the audio bitrate field (only for CBR audio) */
if (!audio_trak->properties->audio.vbr) {
audio_bitrate =
@@ -2958,7 +2977,7 @@ static void demux_qt_send_headers(demux_plugin_t *this
}
buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = audio_trak->properties->audio.codec_buftype;
+ buf->type = audio_trak->properties->audio.codec_buftype | audio_index;
buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END;
buf->decoder_info[0] = 0;
buf->decoder_info[1] = audio_trak->properties->audio.sample_rate;
@@ -2980,7 +2999,7 @@ static void demux_qt_send_headers(demux_plugin_t *this
if( audio_trak->decoder_config ) {
buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = audio_trak->properties->audio.codec_buftype;
+ buf->type = audio_trak->properties->audio.codec_buftype | audio_index;
buf->size = 0;
buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER;
buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG;
@@ -2996,9 +3015,10 @@ static void demux_qt_send_headers(demux_plugin_t *this
buf->decoder_info[2] = audio_trak->properties->audio.properties_atom_size;
buf->decoder_info_ptr[2] = audio_trak->properties->audio.properties_atom;
buf->size = 0;
- buf->type = audio_trak->properties->audio.codec_buftype;
+ buf->type = audio_trak->properties->audio.codec_buftype | audio_index;
this->audio_fifo->put (this->audio_fifo, buf);
+ this->qt->audio_trak_count = ++audio_index;
}
}
@@ -3069,7 +3089,8 @@ static int demux_qt_seek (demux_plugin_t *this_gen,
demux_qt_t *this = (demux_qt_t *) this_gen;
qt_trak *video_trak = NULL;
qt_trak *audio_trak = NULL;
- int64_t keyframe_pts;
+ int i;
+ int64_t keyframe_pts = -1;
start_pos = (off_t) ( (double) start_pos / 65535 *
this->data_size );
@@ -3089,32 +3110,32 @@ static int demux_qt_seek (demux_plugin_t *this_gen,
this->status = binary_seek(video_trak, start_pos, start_time);
if (this->status != DEMUX_OK)
return this->status;
- }
-
- if (this->qt->audio_trak != -1) {
- audio_trak = &this->qt->traks[this->qt->audio_trak];
- this->status = binary_seek(audio_trak, start_pos, start_time);
- if (this->status != DEMUX_OK)
- return this->status;
- }
-
- /* search back in the video trak for the nearest keyframe */
- if (video_trak)
+ /* search back in the video trak for the nearest keyframe */
while (video_trak->current_frame) {
if (video_trak->frames[video_trak->current_frame].keyframe) {
break;
}
video_trak->current_frame--;
}
+ keyframe_pts = video_trak->frames[video_trak->current_frame].pts;
+ }
+ /* seek all supported audio traks */
+ for (i = 0; i < this->qt->audio_trak_count; i++) {
+ audio_trak = &this->qt->traks[this->qt->audio_traks[i]];
+ this->status = binary_seek(audio_trak, start_pos, start_time);
+ if (this->status != DEMUX_OK)
+ return this->status;
+ }
+
/* not done yet; now that the nearest keyframe has been found, seek
* back to the first audio frame that has a pts less than or equal to
* that of the keyframe; do not go through with this process there is
* no video trak */
- if (audio_trak && video_trak) {
- keyframe_pts = video_trak->frames[video_trak->current_frame].pts;
+ if (keyframe_pts >= 0) for (i = 0; i < this->qt->audio_trak_count; i++) {
+ audio_trak = &this->qt->traks[this->qt->audio_traks[i]];
while (audio_trak->current_frame) {
- if (audio_trak->frames[audio_trak->current_frame].pts < keyframe_pts) {
+ if (audio_trak->frames[audio_trak->current_frame].pts <= keyframe_pts) {
break;
}
audio_trak->current_frame--;
@@ -3158,11 +3179,39 @@ static int demux_qt_get_stream_length (demux_plugin_t
}
static uint32_t demux_qt_get_capabilities(demux_plugin_t *this_gen) {
- return DEMUX_CAP_NOCAP;
+ return DEMUX_CAP_AUDIOLANG;
}
static int demux_qt_get_optional_data(demux_plugin_t *this_gen,
void *data, int data_type) {
+ demux_qt_t *this = (demux_qt_t *) this_gen;
+
+ /* be a bit paranoid */
+ if (this == NULL || this->stream == NULL)
+ return DEMUX_OPTIONAL_UNSUPPORTED;
+
+ switch (data_type) {
+ case DEMUX_OPTIONAL_DATA_AUDIOLANG: {
+ char *str = data;
+ int channel = *((int *)data);
+ if ((channel < 0) || (channel >= this->qt->audio_trak_count)) {
+ strcpy (str, "none");
+ } else {
+ int lang = this->qt->traks[this->qt->audio_traks[channel]].lang;
+ if ((lang < 0x400) || (lang == 0x7fff)) {
+ sprintf (str, "%d", channel);
+ } else {
+ int i;
+ for (i = 10; i >= 0; i -= 5)
+ *str++ = 0x60 | ((lang >> i) & 0x1f);
+ *str = 0;
+ }
+ return DEMUX_OPTIONAL_SUCCESS;
+ }
+ }
+ break;
+ default: ;
+ }
return DEMUX_OPTIONAL_UNSUPPORTED;
}

View File

@ -1,273 +0,0 @@
$OpenBSD: patch-src_demuxers_demux_real_c,v 1.1 2013/11/30 22:13:37 brad Exp $
- Fix realvideo reordered pts.
- Better a/v sync.
--- src/demuxers/demux_real.c.orig Wed Nov 20 19:25:44 2013
+++ src/demuxers/demux_real.c Wed Nov 20 21:08:18 2013
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2012 the xine project
+ * Copyright (C) 2000-2013 the xine project
*
* This file is part of xine, a free video player.
*
@@ -122,6 +122,7 @@ typedef struct {
uint8_t *frame_buffer;
uint32_t frame_num_bytes;
uint32_t sub_packet_cnt;
+ uint32_t audio_time;
} real_stream_t;
typedef struct {
@@ -158,13 +159,7 @@ typedef struct {
int64_t last_pts[2];
int send_newpts;
- int buf_flag_seek;
- uint32_t last_ts;
- uint32_t next_ts;
- int last_seq;
- int next_seq;
-
int fragment_size; /* video sub-demux */
int fragment_count;
uint32_t *fragment_tab;
@@ -976,96 +971,72 @@ static int demux_real_parse_references( demux_real_t *
#define WRAP_THRESHOLD 220000
#define PTS_AUDIO 0
#define PTS_VIDEO 1
+#define PTS_BOTH 2
static void check_newpts (demux_real_t *this, int64_t pts, int video, int preview) {
const int64_t diff = pts - this->last_pts[video];
- lprintf ("check_newpts %"PRId64"\n", pts);
- if (!preview && pts &&
- (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) {
+ if (preview)
+ return;
- lprintf ("diff=%"PRId64"\n", diff);
-
- if (this->buf_flag_seek) {
- _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK);
- this->buf_flag_seek = 0;
- } else {
- _x_demux_control_newpts(this->stream, pts, 0);
- }
- this->send_newpts = 0;
- this->last_pts[1-video] = 0;
+ /* Metronom does not strictly follow audio pts. They usually are too coarse
+ for seamless playback. Instead, it takes the latest discontinuity as a
+ starting point. This can lead to terrible lags for our very long audio frames.
+ So let's make sure audio has the last word here. */
+ if (this->send_newpts > video) {
+ _x_demux_control_newpts (this->stream, pts, BUF_FLAG_SEEK);
+ this->send_newpts = video;
+ this->last_pts[video] = pts;
+ this->last_pts[1 - video] = 0;
+ } else if (pts && (this->last_pts[video]) && (abs (diff) > WRAP_THRESHOLD)) {
+ _x_demux_control_newpts (this->stream, pts, 0);
+ this->send_newpts = 0;
+ this->last_pts[1 - video] = 0;
}
- if (!preview && pts )
+ if (pts)
this->last_pts[video] = pts;
}
-static uint32_t real_fix_timestamp (demux_real_t *this, uint8_t *hdr, uint32_t ts_in) {
- int pict_type;
- int seq;
- uint32_t ts_out;
-
- switch(this->video_stream->buf_type) {
+static uint32_t real_get_reordered_pts (demux_real_t *this, uint8_t *hdr, uint32_t dts) {
+ int pict_type; /* I1/I2/P/B-frame */
+ uint32_t t, pts;
+ /* lower 13 bits of pts are stored within the frame */
+ pict_type = hdr[0];
+ t = ((((uint32_t)hdr[1] << 8) | hdr[2]) << 8) | hdr[3];
+ switch (this->video_stream->buf_type) {
case BUF_VIDEO_RV20:
- pict_type = (hdr[0] & 0xC0) >> 6;
- seq = ((hdr[1] & 0x7F) << 6) + ((hdr[2] & 0xFC) >> 2);
- break;
+ pict_type >>= 6;
+ t >>= 10;
+ break;
case BUF_VIDEO_RV30:
- pict_type = (hdr[0] & 0x18) >> 3;
- seq = ((hdr[1] & 0x0F) << 9) + (hdr[2] << 1) + ((hdr[3] & 0x80) >> 7);
- break;
+ pict_type >>= 3;
+ t >>= 7;
+ break;
case BUF_VIDEO_RV40:
- pict_type = (hdr[0] & 0x60) >> 5;
- seq = ((hdr[1] & 0x07) << 10) + (hdr[2] << 2) + ((hdr[3] & 0xC0) >> 6);
- break;
+ pict_type >>= 5;
+ t >>= 6;
+ break;
default:
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"demux_real: can't fix timestamp for buf type 0x%08x\n",
this->video_stream->buf_type);
- return ts_in;
- break;
+ return (dts);
+ break;
}
- switch (pict_type) {
- case 0:
- case 1:
- /* I frame */
- ts_out = this->next_ts;
-
- this->last_ts = this->next_ts;
- this->next_ts = ts_in;
-
- this->last_seq = this->next_seq;
- this->next_seq = seq;
- break;
- case 2:
- /* P frame */
- ts_out = this->next_ts;
-
- this->last_ts = this->next_ts;
- if (seq < this->next_seq)
- this->next_ts += seq + 8192 - this->next_seq;
- else
- this->next_ts += seq - this->next_seq;
-
- this->last_seq = this->next_seq;
- this->next_seq = seq;
- break;
- case 3:
- /* B frame */
- if (seq < this->last_seq)
- ts_out = ((seq + 8192 - this->last_seq) + this->last_ts);
- else
- ts_out = ((seq - this->last_seq) + this->last_ts);
- break;
- default:
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_real: unknown pict_type: %d\n", pict_type);
- ts_out = 0;
- break;
+ pict_type &= 3;
+ t &= 0x1fff;
+ pts = (dts & (~0x1fff)) | t;
+ /* snap to dts +/- 4.095 seconds */
+ if (dts + 0x1000 < pts) pts -= 0x2000;
+ else if (dts > pts + 0x1000) pts += 0x2000;
+ if (this->stream->xine->verbosity == XINE_VERBOSITY_DEBUG + 1) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1,
+ "demux_real: video pts: %d.%03d:%04d -> %d.%03d (%d)\n",
+ dts / 1000, dts % 1000, t, pts / 1000, pts % 1000, pict_type);
}
-
- return ts_out;
+ return (pts);
}
static int stream_read_char (demux_real_t *this) {
@@ -1121,7 +1092,7 @@ static int demux_real_send_chunk(demux_plugin_t *this_
const uint16_t stream = _X_BE_16(&header[4]);
const off_t offset __attr_unused = this->input->get_current_pos(this->input);
uint16_t size = _X_BE_16(&header[2]) - DATA_PACKET_HEADER_SIZE;
- const uint32_t timestamp= _X_BE_32(&header[6]);
+ uint32_t timestamp= _X_BE_32(&header[6]);
int64_t pts = (int64_t) timestamp * 90;
/* Data packet header with version 1 contains 1 extra byte */
@@ -1330,14 +1301,14 @@ static int demux_real_send_chunk(demux_plugin_t *this_
/* if the video stream has b-frames fix the timestamps */
if((this->video_stream->format >= 0x20200002) &&
(buf->decoder_flags & BUF_FLAG_FRAME_START))
- pts = (int64_t) real_fix_timestamp(this, buf->content, timestamp) * 90;
+ pts = (int64_t)real_get_reordered_pts (this, buf->content, timestamp) * 90;
/* this test was moved from ffmpeg video decoder.
* fixme: is pts only valid on frame start? */
- if( buf->decoder_flags & BUF_FLAG_FRAME_START )
+ if (buf->decoder_flags & BUF_FLAG_FRAME_START) {
buf->pts = pts;
- else
- buf->pts = 0;
+ check_newpts (this, pts, PTS_VIDEO, 0);
+ } else buf->pts = 0;
pts = 0;
buf->extra_info->input_normpos = normpos;
@@ -1371,6 +1342,35 @@ static int demux_real_send_chunk(demux_plugin_t *this_
else
this->audio_need_keyframe = 0;
+ /* speed up when not debugging */
+ if (this->stream->xine->verbosity == XINE_VERBOSITY_DEBUG + 1) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1,
+ "demux_real: audio pts: %d.%03d %s%s\n",
+ timestamp / 1000, timestamp % 1000,
+ keyframe ? "*" : " ",
+ this->audio_stream->sub_packet_cnt ? " " : "s");
+ }
+
+ /* cook audio frames are fairly long (almost 2 seconds). For obfuscation
+ purposes, they are sent as multiple fragments in intentionally wrong order.
+ The first sent fragment has the timestamp for the whole frame.
+
+ Sometimes, the remaining fragments all carry the same time, and appear
+ immediately thereafter. This is easy.
+
+ Sometimes, the remaining fragments carry fake timestamps interpolated across
+ the frame duration. Consequently, they will be muxed between the next few
+ video frames. We get the complete frame ~2 seconds late. This is ugly.
+ Let's be careful not to trap metronom into a big lag. */
+ if (!this->audio_stream->sub_packet_cnt)
+ this->audio_stream->audio_time = timestamp;
+ else
+ timestamp = this->audio_stream->audio_time;
+ /* nasty kludge, maybe this is somewhere in mdpr? */
+ if (this->audio_stream->buf_type == BUF_AUDIO_COOK)
+ timestamp += 120;
+ pts = (int64_t) timestamp * 90;
+
/* if we have a seekable stream then use the timestamp for the data
* packet for more accurate seeking - if not then estimate time using
* average bitrate */
@@ -1549,6 +1549,7 @@ static void demux_real_send_headers(demux_plugin_t *th
this->last_pts[0] = 0;
this->last_pts[1] = 0;
+ this->send_newpts = PTS_BOTH;
this->avg_bitrate = 1;
@@ -1624,7 +1625,6 @@ static int demux_real_seek (demux_plugin_t *this_gen,
if(this->audio_stream)
this->audio_stream->sub_packet_cnt = 0;
- this->buf_flag_seek = 1;
_x_demux_flush_engine(this->stream);
}
}
@@ -1636,12 +1636,9 @@ static int demux_real_seek (demux_plugin_t *this_gen,
this->input->seek_time(this->input, start_time, SEEK_SET);
}
- this->send_newpts = 1;
+ this->send_newpts = PTS_BOTH;
this->old_seqnum = -1;
this->fragment_size = 0;
-
- this->next_ts = 0;
- this->next_seq = 0;
this->status = DEMUX_OK;

View File

@ -1,22 +0,0 @@
$OpenBSD: patch-src_libreal_xine_real_video_decoder_c,v 1.1 2013/11/30 22:13:37 brad Exp $
Fix realvideo reordered pts.
--- src/libreal/xine_real_video_decoder.c.orig Wed Nov 20 21:08:49 2013
+++ src/libreal/xine_real_video_decoder.c Wed Nov 20 21:09:13 2013
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2011 the xine project
+ * Copyright (C) 2000-2013 the xine project
*
* This file is part of xine, a free video player.
*
@@ -420,7 +420,7 @@ static void realdec_decode_data (video_decoder_t *this
XINE_IMGFMT_YV12,
VO_BOTH_FIELDS);
- img->pts = this->pts;
+ img->pts = (int64_t)transform_out.timestamp * 90;
img->duration = this->duration;
_x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->duration);
img->bad_frame = 0;

View File

@ -1,7 +1,7 @@
$OpenBSD: patch-src_post_deinterlace_plugins_Makefile_in,v 1.14 2013/11/30 22:13:37 brad Exp $
--- src/post/deinterlace/plugins/Makefile.in.orig Mon Sep 23 16:58:17 2013
+++ src/post/deinterlace/plugins/Makefile.in Wed Nov 20 16:57:34 2013
@@ -592,7 +592,7 @@ noinst_HEADERS = plugins.h greedyhmacros.h
$OpenBSD: patch-src_post_deinterlace_plugins_Makefile_in,v 1.15 2014/04/16 05:09:00 brad Exp $
--- src/post/deinterlace/plugins/Makefile.in.orig Tue Apr 8 11:04:17 2014
+++ src/post/deinterlace/plugins/Makefile.in Wed Apr 9 22:07:16 2014
@@ -597,7 +597,7 @@ noinst_HEADERS = plugins.h greedyhmacros.h
# doesn't run out of general registers trying to compile it.
noinst_LTLIBRARIES = libdeinterlacepluginsO1.la libdeinterlaceplugins.la
libdeinterlacepluginsO1_la_SOURCES = kdetv_greedyh.c $(debug_sources)

View File

@ -1,14 +0,0 @@
$OpenBSD: patch-src_xine-engine_buffer_types_c,v 1.3 2013/11/30 22:13:37 brad Exp $
Simple (E)AC3 support.
--- src/xine-engine/buffer_types.c.orig Wed Nov 20 17:06:37 2013
+++ src/xine-engine/buffer_types.c Wed Nov 20 17:07:19 2013
@@ -808,6 +808,7 @@ static const audio_db_t audio_db[] = {
{
0x2000,
ME_FOURCC('m', 's', 0x20, 0x00),
+ ME_FOURCC('a', 'c', '-', '3'),
0
},
BUF_AUDIO_A52,