mirror of
https://github.com/mpv-player/mpv
synced 2024-12-25 08:12:17 +00:00
demux_lavf: add a hack to work around other hacks
mplayer (and all forks) use a single FourCC field to map codecs. This is what sh_video->format and sh_audio->format is used for. Basically it's a key into the codecs.conf table to find out what decoder to use. (There's only one video codec and one major audio codec left - both libavcodec. But we still have to deal with mapping coming from non-libavformat demuxers.) It seems this causes some video codecs to fail, such as WV1F in AVI [1]. demux_lavf generally throws away the codec_tag from libavformat if the codec is MPEG-in-AVI. There are probably other cases like this. Add a hack to enforce passing the correct codec tag when only ffmpeg demuxers and decoders involved. Note: the sample [1] needs to be flipped. With --demuxer=avi, this is done correctly, because unlike demux_lavf, the demuxer uses the FourCC directly for the sh_video->format tag, and finds the correct codecs.conf entry (which contains the flip flag). We could just add a "whitelist" of codec tags which can be passed through to sh_video->format, but I don't want to do that just for such an obscure format as the sample at hand. Note 2: when demux_lavf is used, the AVCodecContext could be passed directly to vd_ffmpeg/ad_ffmpeg. The code to convert to/from the internal mplayer stream headers is probably still needed, as there are non-ffmpeg demuxers and audio decoders. [1] http://samples.mplayerhq.hu/V-codecs/WV1F/AVI/title2.avi
This commit is contained in:
parent
0c95e139a9
commit
219e1ab1e7
@ -159,6 +159,8 @@ static int init(sh_audio_t *sh_audio)
|
||||
}
|
||||
lavc_context->request_channels = opts->audio_output_channels;
|
||||
lavc_context->codec_tag = sh_audio->format; //FOURCC
|
||||
if (sh_audio->gsh->lavf_codec_tag)
|
||||
lavc_context->codec_tag = sh_audio->gsh->lavf_codec_tag;
|
||||
lavc_context->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||
lavc_context->codec_id = lavc_codec->id; // not sure if required, imho not --A'rpi
|
||||
|
||||
|
@ -239,6 +239,8 @@ static int init(sh_video_t *sh)
|
||||
} else {
|
||||
avctx->pix_fmt = rawfmt;
|
||||
}
|
||||
if (sh->gsh->lavf_codec_tag)
|
||||
avctx->codec_tag = sh->gsh->lavf_codec_tag;
|
||||
avctx->stream_codec_tag = sh->video.fccHandler;
|
||||
avctx->idct_algo = lavc_param->idct_algo;
|
||||
avctx->error_concealment = lavc_param->error_concealment;
|
||||
|
@ -292,6 +292,8 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i)
|
||||
int stream_id;
|
||||
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
|
||||
AVDictionaryEntry *title = av_dict_get(st->metadata, "title", NULL, 0);
|
||||
// Work around collisions resulting from the hacks changing codec_tag.
|
||||
int lavf_codec_tag = codec->codec_tag;
|
||||
// Don't use native MPEG codec tag values with our generic tag tables.
|
||||
// May contain for example value 3 for MP3, which we'd map to PCM audio.
|
||||
if (matches_avinputformat_name(priv, "mpeg") ||
|
||||
@ -320,6 +322,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i)
|
||||
stream_type = "audio";
|
||||
priv->astreams[priv->audio_streams] = i;
|
||||
sh_audio->libav_codec_id = codec->codec_id;
|
||||
sh_audio->gsh->lavf_codec_tag = lavf_codec_tag;
|
||||
wf = calloc(sizeof(*wf) + codec->extradata_size, 1);
|
||||
// mp4a tag is used for all mp4 files no matter what they actually contain
|
||||
if (codec->codec_tag == MKTAG('m', 'p', '4', 'a'))
|
||||
@ -403,6 +406,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i)
|
||||
stream_type = "video";
|
||||
priv->vstreams[priv->video_streams] = i;
|
||||
sh_video->libav_codec_id = codec->codec_id;
|
||||
sh_video->gsh->lavf_codec_tag = lavf_codec_tag;
|
||||
bih = calloc(sizeof(*bih) + codec->extradata_size, 1);
|
||||
|
||||
if (codec->codec_id == CODEC_ID_RAWVIDEO) {
|
||||
@ -517,6 +521,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i)
|
||||
stream_type = "subtitle";
|
||||
priv->sstreams[priv->sub_streams] = i;
|
||||
sh_sub->libav_codec_id = codec->codec_id;
|
||||
sh_sub->gsh->lavf_codec_tag = lavf_codec_tag;
|
||||
sh_sub->type = type;
|
||||
if (codec->extradata_size) {
|
||||
sh_sub->extradata = malloc(codec->extradata_size);
|
||||
|
@ -54,6 +54,9 @@ struct sh_stream {
|
||||
struct sh_video *video;
|
||||
struct sh_sub *sub;
|
||||
|
||||
// Work around other hacks.
|
||||
int lavf_codec_tag;
|
||||
|
||||
char *title;
|
||||
bool default_track;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user