mirror of
https://github.com/mpv-player/mpv
synced 2024-12-21 06:14:32 +00:00
5e50fe3049
This fixes when resuming certain broken h264 files encoded by x264. See FFmpeg commit 840b41b2a643fc8f0617c0370125a19c02c6b586 about the x264 bug itself. Normally, the unregistered user data SEI (that contains the x264 version string) is informational only. But libavcodec uses it to workaround a x264 bug, which was recently fixed in both libavcodec and x264. The fact that both encoder and decoder were buggy is the reason that it was not found earlier, and there are apparently a lot of files around created by the broken decoder. If libavcodec sees the SEI, this bug can be worked around by using the old behavior. If you resume a file with mpv (i.e. seeking when the file loads), libavcodec never sees the first video packet. Consequently it has to assume the file is not broken, and never applies the workaround, resulting in garbage being played. Fix this by always feeding the first video packet to the decoder on init, and then flushing the codec (to avoid that an unwanted image is output). Flushing the codec does not remove info such as the x264 version. We also abuse the fact that the first avcodec_send_packet() always pushes the frame into the decoder (so we don't have to trigger the decoder by requsting an output frame).
112 lines
3.5 KiB
C
112 lines
3.5 KiB
C
/*
|
|
* This file is part of mpv.
|
|
*
|
|
* mpv is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* mpv 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 Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef MPLAYER_STHEADER_H
|
|
#define MPLAYER_STHEADER_H
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include "common/common.h"
|
|
#include "audio/chmap.h"
|
|
#include "video/mp_image.h"
|
|
|
|
struct MPOpts;
|
|
struct demuxer;
|
|
|
|
// Stream headers:
|
|
|
|
struct sh_stream {
|
|
enum stream_type type;
|
|
// 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;
|
|
// FFmpeg stream index (AVFormatContext.streams[index]), or equivalent.
|
|
int ff_index;
|
|
|
|
struct mp_codec_params *codec;
|
|
|
|
char *title;
|
|
char *lang; // language code
|
|
bool default_track; // container default track flag
|
|
bool forced_track; // container forced track flag
|
|
int hls_bitrate;
|
|
|
|
struct mp_tags *tags;
|
|
|
|
bool missing_timestamps;
|
|
|
|
// stream is a picture (such as album art)
|
|
struct demux_packet *attached_picture;
|
|
|
|
// Internal to demux.c
|
|
struct demux_stream *ds;
|
|
};
|
|
|
|
struct mp_codec_params {
|
|
enum stream_type type;
|
|
|
|
// E.g. "h264" (usually corresponds to AVCodecDescriptor.name)
|
|
const char *codec;
|
|
|
|
// Usually a FourCC, exact meaning depends on codec.
|
|
unsigned int codec_tag;
|
|
|
|
unsigned char *extradata; // codec specific per-stream header
|
|
int extradata_size;
|
|
|
|
// Codec specific header data (set by demux_lavf.c only)
|
|
struct AVCodecParameters *lav_codecpar;
|
|
|
|
// Timestamp granularity for converting double<->rational timestamps.
|
|
int native_tb_num, native_tb_den;
|
|
|
|
// Used by an obscure bug workaround mechanism. As an exception to the usual
|
|
// rules, demuxers are allowed to set this after adding the sh_stream, but
|
|
// only before the demuxer open call returns.
|
|
struct demux_packet *first_packet;
|
|
|
|
// STREAM_AUDIO
|
|
int samplerate;
|
|
struct mp_chmap channels;
|
|
bool force_channels;
|
|
int bitrate; // compressed bits/sec
|
|
int block_align;
|
|
struct replaygain_data *replaygain_data;
|
|
|
|
// STREAM_VIDEO
|
|
bool avi_dts; // use DTS timing; first frame and DTS is 0
|
|
double fps; // frames per second (set only if constant fps)
|
|
bool reliable_fps; // the fps field is definitely not broken
|
|
int par_w, par_h; // pixel aspect ratio (0 if unknown/square)
|
|
int disp_w, disp_h; // display size
|
|
int rotate; // intended display rotation, in degrees, [0, 359]
|
|
int stereo_mode; // mp_stereo3d_mode (0 if none/unknown)
|
|
struct mp_colorspace color; // colorspace info where available
|
|
struct mp_spherical_params spherical;
|
|
|
|
// STREAM_VIDEO + STREAM_AUDIO
|
|
int bits_per_coded_sample;
|
|
|
|
// STREAM_SUB
|
|
double frame_based; // timestamps are frame-based (and this is the
|
|
// fallback framerate used for timestamps)
|
|
};
|
|
|
|
#endif /* MPLAYER_STHEADER_H */
|