1
mirror of https://github.com/mpv-player/mpv synced 2024-10-26 07:22:17 +02:00
mpv/demux/stheader.h
wm4 dc0b2046cd video: add insane hack to work around FFmpeg/Libav insanity
So, FFmpeg/Libav requires us to figure out video timestamps ourselves
(see last 10 commits or so), but the methods it provides for this aren't
even sufficient. In particular, everything that uses AVI-style DTS (avi,
vfw-muxed mkv, possibly mpeg4-in-ogm) with a codec that has an internal
frame delay is broken. In this case, libavcodec will shift the packet-
to-image correspondence by the codec delay, meaning that with a delay=1,
the first AVFrame.pkt_dts is not 0, but that of the second packet. All
timestamps will appear shifted. The start time (e.g. the time displayed
when doing "mpv file.avi --pause") will not be exactly 0.

(According to Libav developers, this is how it's supposed to work; just
that the first DTS values are normally negative with formats that use
DTS "properly". Who cares if it doesn't work at all with very common
video formats? There's no indication that they'll fix this soon,
either. An elegant workaround is missing too.)

Add a hack to re-enable the old PTS code for AVI and vfw-muxed MKV.
Since these timestamps are not reorderd, we wouldn't need to sort them,
but it's less code this way (and possibly more robust, should a demuxer
unexpectedly output PTS).

The original intention of all the timestamp changes recently was
actually to get rid of demuxer-specific hacks and the old timestamp
sorting code, but it looks like this didn't work out. Yet another case
where trying to replace native MPlayer functionality with FFmpeg/Libav
led to disadvantages and bugs. (Note that the old PTS sorting code
doesn't and can't handle frame dropping correctly, though.)

Bug reports:

 https://trac.ffmpeg.org/ticket/3178

 https://bugzilla.libav.org/show_bug.cgi?id=600
2013-11-28 15:20:33 +01:00

97 lines
3.1 KiB
C

/*
* This file is part of MPlayer.
*
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPLAYER_STHEADER_H
#define MPLAYER_STHEADER_H
#include <stdbool.h>
#include "mpvcore/mp_common.h"
#include "audio/chmap.h"
#include "ms_hdr.h"
struct MPOpts;
struct demuxer;
// Stream headers:
struct sh_stream {
enum stream_type type;
struct demuxer *demuxer;
// Index into demuxer->streams.
int index;
// Demuxer/format specific ID. Corresponds to the stream IDs as encoded in
// some file formats (e.g. MPEG), or an index chosen by demux.c.
int demuxer_id;
// One of these is non-NULL, the others are NULL, depending on the stream
// type.
struct sh_audio *audio;
struct sh_video *video;
struct sh_sub *sub;
// E.g. "h264" (usually corresponds to AVCodecDescriptor.name)
const char *codec;
// Usually a FourCC, exact meaning depends on codec.
unsigned int format;
// Codec specific header data (set by demux_lavf.c)
// Other demuxers use sh_audio->wf and sh_video->bih instead.
struct AVCodecContext *lav_headers;
char *title;
char *lang; // language code
bool default_track; // container default track flag
// stream is a picture (such as album art)
struct demux_packet *attached_picture;
// Internal to demux.c
struct demux_stream *ds;
};
typedef struct sh_audio {
int samplerate;
struct mp_chmap channels;
int i_bps; // == bitrate (compressed bytes/sec)
// win32-compatible codec parameters:
MP_WAVEFORMATEX *wf;
// note codec extradata may be either under "wf" or "codecdata"
unsigned char *codecdata;
int codecdata_len;
} sh_audio_t;
typedef struct sh_video {
bool avi_dts; // use DTS timing; first frame and DTS is 0
float fps; // frames per second (set only if constant fps)
float aspect; // aspect ratio stored in the file (for prescaling)
int i_bps; // == bitrate (compressed bytes/sec)
int disp_w, disp_h; // display size
MP_BITMAPINFOHEADER *bih;
} sh_video_t;
typedef struct sh_sub {
unsigned char *extradata; // extra header data passed from demuxer
int extradata_len;
int frame_based; // timestamps are frame-based
bool is_utf8; // if false, subtitle packet charset is unknown
struct ass_track *track; // loaded by libass
struct dec_sub *dec_sub; // decoder context
} sh_sub_t;
#endif /* MPLAYER_STHEADER_H */