Update to Xine-lib 1.2.5.
ok juanfra@
This commit is contained in:
parent
08da790645
commit
5ec30566a2
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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' >$@
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(¤t_atom[4]);
|
||||
const uint32_t current_atom_size = _X_BE_32(¤t_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(¤t_atom[12]);
|
||||
+ /*handler_type = _X_BE_32(¤t_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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
@ -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)
|
||||
|
@ -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,
|
Loading…
x
Reference in New Issue
Block a user