mirror of https://github.com/mpv-player/mpv
recorder: add support for attachments (fonts)
Though, only when the output format is matroska, to avoid muxing errors. This is quite useful when the input has ASS subtitles, as they tend to rely on embedded fonts.
This commit is contained in:
parent
f9527497c6
commit
4d3df1c842
|
@ -23,6 +23,7 @@
|
|||
#include "common/common.h"
|
||||
#include "common/global.h"
|
||||
#include "common/msg.h"
|
||||
#include "demux/demux.h"
|
||||
#include "demux/packet.h"
|
||||
#include "demux/stheader.h"
|
||||
|
||||
|
@ -119,7 +120,9 @@ static int add_stream(struct mp_recorder *priv, struct sh_stream *sh)
|
|||
struct mp_recorder *mp_recorder_create(struct mpv_global *global,
|
||||
const char *target_file,
|
||||
struct sh_stream **streams,
|
||||
int num_streams)
|
||||
int num_streams,
|
||||
struct demux_attachment **attachments,
|
||||
int num_attachments)
|
||||
{
|
||||
struct mp_recorder *priv = talloc_zero(NULL, struct mp_recorder);
|
||||
|
||||
|
@ -153,6 +156,35 @@ struct mp_recorder *mp_recorder_create(struct mpv_global *global,
|
|||
}
|
||||
}
|
||||
|
||||
if (!strcmp(priv->mux->oformat->name, "matroska")) {
|
||||
// Only attach attachments (fonts) to matroska - mp4, nut, mpegts don't
|
||||
// like them, and we find that out too late in the muxing process.
|
||||
AVStream *a_stream = NULL;
|
||||
for (int i = 0; i < num_attachments; ++i) {
|
||||
a_stream = avformat_new_stream(priv->mux, NULL);
|
||||
if (!a_stream) {
|
||||
MP_ERR(priv, "Can't mux one of the attachments.\n");
|
||||
goto error;
|
||||
}
|
||||
struct demux_attachment *attachment = attachments[i];
|
||||
|
||||
a_stream->codecpar->codec_type = AVMEDIA_TYPE_ATTACHMENT;
|
||||
|
||||
a_stream->codecpar->extradata = av_mallocz(
|
||||
attachment->data_size + AV_INPUT_BUFFER_PADDING_SIZE
|
||||
);
|
||||
if (!a_stream->codecpar->extradata) {
|
||||
goto error;
|
||||
}
|
||||
memcpy(a_stream->codecpar->extradata,
|
||||
attachment->data, attachment->data_size);
|
||||
a_stream->codecpar->extradata_size = attachment->data_size;
|
||||
|
||||
av_dict_set(&a_stream->metadata, "filename", attachment->name, 0);
|
||||
av_dict_set(&a_stream->metadata, "mimetype", attachment->type, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Not sure how to write this in a "standard" way. It appears only mkv
|
||||
// and mp4 support this directly.
|
||||
char version[200];
|
||||
|
|
|
@ -5,12 +5,15 @@ struct mp_recorder;
|
|||
struct mpv_global;
|
||||
struct demux_packet;
|
||||
struct sh_stream;
|
||||
struct demux_attachment;
|
||||
struct mp_recorder_sink;
|
||||
|
||||
struct mp_recorder *mp_recorder_create(struct mpv_global *global,
|
||||
const char *target_file,
|
||||
struct sh_stream **streams,
|
||||
int num_streams);
|
||||
int num_streams,
|
||||
struct demux_attachment **demux_attachments,
|
||||
int num_attachments);
|
||||
void mp_recorder_destroy(struct mp_recorder *r);
|
||||
void mp_recorder_mark_discontinuity(struct mp_recorder *r);
|
||||
|
||||
|
|
|
@ -1944,9 +1944,18 @@ static struct mp_recorder *recorder_create(struct demux_internal *in,
|
|||
if (stream->ds->selected)
|
||||
MP_TARRAY_APPEND(NULL, streams, num_streams, stream);
|
||||
}
|
||||
|
||||
struct demuxer *demuxer = in->d_thread;
|
||||
struct demux_attachment **attachments = talloc_array(NULL, struct demux_attachment*, demuxer->num_attachments);
|
||||
for (int n = 0; n < demuxer->num_attachments; n++) {
|
||||
attachments[n] = &demuxer->attachments[n];
|
||||
}
|
||||
|
||||
struct mp_recorder *res = mp_recorder_create(in->d_thread->global, dst,
|
||||
streams, num_streams);
|
||||
streams, num_streams,
|
||||
attachments, demuxer->num_attachments);
|
||||
talloc_free(streams);
|
||||
talloc_free(attachments);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -1959,11 +1959,18 @@ void open_recorder(struct MPContext *mpctx, bool on_init)
|
|||
MP_TARRAY_APPEND(NULL, streams, num_streams, track->stream);
|
||||
}
|
||||
|
||||
struct demux_attachment **attachments = talloc_array(NULL, struct demux_attachment*, mpctx->demuxer->num_attachments);
|
||||
for (int n = 0; n < mpctx->demuxer->num_attachments; n++) {
|
||||
attachments[n] = &mpctx->demuxer->attachments[n];
|
||||
}
|
||||
|
||||
mpctx->recorder = mp_recorder_create(mpctx->global, mpctx->opts->record_file,
|
||||
streams, num_streams);
|
||||
streams, num_streams,
|
||||
attachments, mpctx->demuxer->num_attachments);
|
||||
|
||||
if (!mpctx->recorder) {
|
||||
talloc_free(streams);
|
||||
talloc_free(attachments);
|
||||
close_recorder_and_error(mpctx);
|
||||
return;
|
||||
}
|
||||
|
@ -1987,5 +1994,6 @@ void open_recorder(struct MPContext *mpctx, bool on_init)
|
|||
}
|
||||
|
||||
talloc_free(streams);
|
||||
talloc_free(attachments);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue