1 /*
2  * This file is part of mpv.
3  *
4  * mpv is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * mpv is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <math.h>
19 
20 #include <libavformat/avformat.h>
21 
22 #include "common/av_common.h"
23 #include "common/common.h"
24 #include "common/global.h"
25 #include "common/msg.h"
26 #include "demux/demux.h"
27 #include "demux/packet.h"
28 #include "demux/stheader.h"
29 
30 #include "recorder.h"
31 
32 // Maximum number of packets we buffer at most to attempt to resync streams.
33 // Essentially, this should be higher than the highest supported keyframe
34 // interval.
35 #define QUEUE_MAX_PACKETS 256
36 // Number of packets we should buffer at least to determine timestamps (due to
37 // codec delay and frame reordering, and potentially lack of DTS).
38 // Keyframe flags can trigger this earlier.
39 #define QUEUE_MIN_PACKETS 16
40 
41 struct mp_recorder {
42     struct mpv_global *global;
43     struct mp_log *log;
44 
45     struct mp_recorder_sink **streams;
46     int num_streams;
47 
48     bool opened;            // mux context is valid
49     bool muxing;            // we're currently recording (instead of preparing)
50     bool muxing_from_start; // no discontinuity at start
51     bool dts_warning;
52 
53     // The start timestamp of the currently recorded segment (the timestamp of
54     // the first packet of the incoming packet stream).
55     double base_ts;
56     // The output packet timestamp corresponding to base_ts. It's the timestamp
57     // of the first packet of the current segment written to the output.
58     double rebase_ts;
59 
60     AVFormatContext *mux;
61 };
62 
63 struct mp_recorder_sink {
64     struct mp_recorder *owner;
65     struct sh_stream *sh;
66     AVStream *av_stream;
67     double max_out_pts;
68     bool discont;
69     bool proper_eof;
70     struct demux_packet **packets;
71     int num_packets;
72 };
73 
add_stream(struct mp_recorder * priv,struct sh_stream * sh)74 static int add_stream(struct mp_recorder *priv, struct sh_stream *sh)
75 {
76     enum AVMediaType av_type = mp_to_av_stream_type(sh->type);
77     if (av_type == AVMEDIA_TYPE_UNKNOWN)
78         return -1;
79 
80     struct mp_recorder_sink *rst = talloc(priv, struct mp_recorder_sink);
81     *rst = (struct mp_recorder_sink) {
82         .owner = priv,
83         .sh = sh,
84         .av_stream = avformat_new_stream(priv->mux, NULL),
85         .max_out_pts = MP_NOPTS_VALUE,
86     };
87 
88     if (!rst->av_stream)
89         return -1;
90 
91     AVCodecParameters *avp = mp_codec_params_to_av(sh->codec);
92     if (!avp)
93         return -1;
94 
95     // Check if we get the same codec_id for the output format;
96     // otherwise clear it to have a chance at muxing
97     if (av_codec_get_id(priv->mux->oformat->codec_tag,
98                         avp->codec_tag) != avp->codec_id)
99         avp->codec_tag = 0;
100 
101     // We don't know the delay, so make something up. If the format requires
102     // DTS, the result will probably be broken. FFmpeg provides nothing better
103     // yet (unless you demux with libavformat, which contains tons of hacks
104     // that try to determine a PTS).
105     if (!sh->codec->lav_codecpar)
106         avp->video_delay = 16;
107 
108     if (avp->codec_id == AV_CODEC_ID_NONE)
109         return -1;
110 
111     if (avcodec_parameters_copy(rst->av_stream->codecpar, avp) < 0)
112         return -1;
113 
114     rst->av_stream->time_base = mp_get_codec_timebase(sh->codec);
115 
116     MP_TARRAY_APPEND(priv, priv->streams, priv->num_streams, rst);
117     return 0;
118 }
119 
mp_recorder_create(struct mpv_global * global,const char * target_file,struct sh_stream ** streams,int num_streams,struct demux_attachment ** attachments,int num_attachments)120 struct mp_recorder *mp_recorder_create(struct mpv_global *global,
121                                        const char *target_file,
122                                        struct sh_stream **streams,
123                                        int num_streams,
124                                        struct demux_attachment **attachments,
125                                        int num_attachments)
126 {
127     struct mp_recorder *priv = talloc_zero(NULL, struct mp_recorder);
128 
129     priv->global = global;
130     priv->log = mp_log_new(priv, global->log, "recorder");
131 
132     if (!num_streams) {
133         MP_ERR(priv, "No streams.\n");
134         goto error;
135     }
136 
137     priv->mux = avformat_alloc_context();
138     if (!priv->mux)
139         goto error;
140 
141     priv->mux->oformat = av_guess_format(NULL, target_file, NULL);
142     if (!priv->mux->oformat) {
143         MP_ERR(priv, "Output format not found.\n");
144         goto error;
145     }
146 
147     if (avio_open2(&priv->mux->pb, target_file, AVIO_FLAG_WRITE, NULL, NULL) < 0) {
148         MP_ERR(priv, "Failed opening output file.\n");
149         goto error;
150     }
151 
152     for (int n = 0; n < num_streams; n++) {
153         if (add_stream(priv, streams[n]) < 0) {
154             MP_ERR(priv, "Can't mux one of the input streams.\n");
155             goto error;
156         }
157     }
158 
159     if (!strcmp(priv->mux->oformat->name, "matroska")) {
160         // Only attach attachments (fonts) to matroska - mp4, nut, mpegts don't
161         // like them, and we find that out too late in the muxing process.
162         AVStream *a_stream = NULL;
163         for (int i = 0; i < num_attachments; ++i) {
164             a_stream = avformat_new_stream(priv->mux, NULL);
165             if (!a_stream) {
166                 MP_ERR(priv, "Can't mux one of the attachments.\n");
167                 goto error;
168             }
169             struct demux_attachment *attachment = attachments[i];
170 
171             a_stream->codecpar->codec_type = AVMEDIA_TYPE_ATTACHMENT;
172 
173             a_stream->codecpar->extradata  = av_mallocz(
174                 attachment->data_size + AV_INPUT_BUFFER_PADDING_SIZE
175             );
176             if (!a_stream->codecpar->extradata) {
177                 goto error;
178             }
179             memcpy(a_stream->codecpar->extradata,
180                 attachment->data, attachment->data_size);
181             a_stream->codecpar->extradata_size = attachment->data_size;
182 
183             av_dict_set(&a_stream->metadata, "filename", attachment->name, 0);
184             av_dict_set(&a_stream->metadata, "mimetype", attachment->type, 0);
185         }
186     }
187 
188     // Not sure how to write this in a "standard" way. It appears only mkv
189     // and mp4 support this directly.
190     char version[200];
191     snprintf(version, sizeof(version), "%s experimental stream recording "
192              "feature (can generate broken files - please report bugs)",
193              mpv_version);
194     av_dict_set(&priv->mux->metadata, "encoding_tool", version, 0);
195 
196     if (avformat_write_header(priv->mux, NULL) < 0) {
197         MP_ERR(priv, "Writing header failed.\n");
198         goto error;
199     }
200 
201     priv->opened = true;
202     priv->muxing_from_start = true;
203 
204     priv->base_ts = MP_NOPTS_VALUE;
205     priv->rebase_ts = 0;
206 
207     MP_WARN(priv, "This is an experimental feature. Output files might be "
208                   "broken or not play correctly with various players "
209                   "(including mpv itself).\n");
210 
211     return priv;
212 
213 error:
214     mp_recorder_destroy(priv);
215     return NULL;
216 }
217 
flush_packets(struct mp_recorder * priv)218 static void flush_packets(struct mp_recorder *priv)
219 {
220     for (int n = 0; n < priv->num_streams; n++) {
221         struct mp_recorder_sink *rst = priv->streams[n];
222         for (int i = 0; i < rst->num_packets; i++)
223             talloc_free(rst->packets[i]);
224         rst->num_packets = 0;
225     }
226 }
227 
mux_packet(struct mp_recorder_sink * rst,struct demux_packet * pkt)228 static void mux_packet(struct mp_recorder_sink *rst,
229                        struct demux_packet *pkt)
230 {
231     struct mp_recorder *priv = rst->owner;
232     struct demux_packet mpkt = *pkt;
233 
234     double diff = priv->rebase_ts - priv->base_ts;
235     mpkt.pts = MP_ADD_PTS(mpkt.pts, diff);
236     mpkt.dts = MP_ADD_PTS(mpkt.dts, diff);
237 
238     rst->max_out_pts = MP_PTS_MAX(rst->max_out_pts, pkt->pts);
239 
240     AVPacket avpkt;
241     mp_set_av_packet(&avpkt, &mpkt, &rst->av_stream->time_base);
242 
243     avpkt.stream_index = rst->av_stream->index;
244 
245     if (avpkt.duration < 0 && rst->sh->type != STREAM_SUB)
246         avpkt.duration = 0;
247 
248     AVPacket *new_packet = av_packet_clone(&avpkt);
249     if (!new_packet) {
250         MP_ERR(priv, "Failed to allocate packet.\n");
251         return;
252     }
253 
254     if (av_interleaved_write_frame(priv->mux, new_packet) < 0)
255         MP_ERR(priv, "Failed writing packet.\n");
256 }
257 
258 // Write all packets available in the stream queue
mux_packets(struct mp_recorder_sink * rst)259 static void mux_packets(struct mp_recorder_sink *rst)
260 {
261     struct mp_recorder *priv = rst->owner;
262     if (!priv->muxing || !rst->num_packets)
263         return;
264 
265     for (int n = 0; n < rst->num_packets; n++) {
266         mux_packet(rst, rst->packets[n]);
267         talloc_free(rst->packets[n]);
268     }
269 
270     rst->num_packets = 0;
271 }
272 
273 // If there was a discontinuity, check whether we can resume muxing (and from
274 // where).
check_restart(struct mp_recorder * priv)275 static void check_restart(struct mp_recorder *priv)
276 {
277     if (priv->muxing)
278         return;
279 
280     double min_ts = MP_NOPTS_VALUE;
281     double rebase_ts = 0;
282     for (int n = 0; n < priv->num_streams; n++) {
283         struct mp_recorder_sink *rst = priv->streams[n];
284         int min_packets = rst->sh->type == STREAM_VIDEO ? QUEUE_MIN_PACKETS : 1;
285 
286         rebase_ts = MP_PTS_MAX(rebase_ts, rst->max_out_pts);
287 
288         if (rst->num_packets < min_packets) {
289             if (!rst->proper_eof && rst->sh->type != STREAM_SUB)
290                 return;
291             continue;
292         }
293 
294         for (int i = 0; i < min_packets; i++)
295             min_ts = MP_PTS_MIN(min_ts, rst->packets[i]->pts);
296     }
297 
298     // Subtitle only stream (wait longer) or stream without any PTS (fuck it).
299     if (min_ts == MP_NOPTS_VALUE)
300         return;
301 
302     priv->rebase_ts = rebase_ts;
303     priv->base_ts = min_ts;
304 
305     for (int n = 0; n < priv->num_streams; n++) {
306         struct mp_recorder_sink *rst = priv->streams[n];
307         rst->max_out_pts = min_ts;
308     }
309 
310     priv->muxing = true;
311 
312     if (!priv->muxing_from_start)
313         MP_WARN(priv, "Discontinuity at timestamp %f.\n", priv->rebase_ts);
314 }
315 
mp_recorder_destroy(struct mp_recorder * priv)316 void mp_recorder_destroy(struct mp_recorder *priv)
317 {
318     if (priv->opened) {
319         for (int n = 0; n < priv->num_streams; n++) {
320             struct mp_recorder_sink *rst = priv->streams[n];
321             mux_packets(rst);
322         }
323 
324         if (av_write_trailer(priv->mux) < 0)
325             MP_ERR(priv, "Writing trailer failed.\n");
326     }
327 
328     if (priv->mux) {
329         if (avio_closep(&priv->mux->pb) < 0)
330             MP_ERR(priv, "Closing file failed\n");
331 
332         avformat_free_context(priv->mux);
333     }
334 
335     flush_packets(priv);
336     talloc_free(priv);
337 }
338 
339 // This is called on a seek, or when recording was started mid-stream.
mp_recorder_mark_discontinuity(struct mp_recorder * priv)340 void mp_recorder_mark_discontinuity(struct mp_recorder *priv)
341 {
342 
343     for (int n = 0; n < priv->num_streams; n++) {
344         struct mp_recorder_sink *rst = priv->streams[n];
345         mux_packets(rst);
346         rst->discont = true;
347         rst->proper_eof = false;
348     }
349 
350     flush_packets(priv);
351     priv->muxing = false;
352     priv->muxing_from_start = false;
353 }
354 
355 // Get a stream for writing. The pointer is valid until mp_recorder is
356 // destroyed. The stream ptr. is the same as one passed to
357 // mp_recorder_create() (returns NULL if it wasn't).
mp_recorder_get_sink(struct mp_recorder * r,struct sh_stream * stream)358 struct mp_recorder_sink *mp_recorder_get_sink(struct mp_recorder *r,
359                                               struct sh_stream *stream)
360 {
361     for (int n = 0; n < r->num_streams; n++) {
362         struct mp_recorder_sink *rst = r->streams[n];
363         if (rst->sh == stream)
364             return rst;
365     }
366     return NULL;
367 }
368 
369 // Pass a packet to the given stream. The function does not own the packet, but
370 // can create a new reference to it if it needs to retain it. Can be NULL to
371 // signal proper end of stream.
mp_recorder_feed_packet(struct mp_recorder_sink * rst,struct demux_packet * pkt)372 void mp_recorder_feed_packet(struct mp_recorder_sink *rst,
373                              struct demux_packet *pkt)
374 {
375     struct mp_recorder *priv = rst->owner;
376 
377     if (!pkt) {
378         rst->proper_eof = true;
379         check_restart(priv);
380         mux_packets(rst);
381         return;
382     }
383 
384     if (pkt->dts == MP_NOPTS_VALUE && !priv->dts_warning) {
385         // No, FFmpeg has no actually usable helpers to generate correct DTS.
386         // No, FFmpeg doesn't tell us which formats need DTS at all.
387         // No, we can not shut up the FFmpeg warning, which will follow.
388         MP_WARN(priv, "Source stream misses DTS on at least some packets!\n"
389                       "If the target file format requires DTS, the written "
390                       "file will be invalid.\n");
391         priv->dts_warning = true;
392     }
393 
394     if (rst->discont && !pkt->keyframe)
395         return;
396     rst->discont = false;
397 
398     if (rst->num_packets >= QUEUE_MAX_PACKETS) {
399         MP_ERR(priv, "Stream %d has too many queued packets; dropping.\n",
400                rst->av_stream->index);
401         return;
402     }
403 
404     pkt = demux_copy_packet(pkt);
405     if (!pkt)
406         return;
407     MP_TARRAY_APPEND(rst, rst->packets, rst->num_packets, pkt);
408 
409     check_restart(priv);
410     mux_packets(rst);
411 }
412