FFmpeg
hdsenc.c
Go to the documentation of this file.
1 /*
2  * Live HDS fragmenter
3  * Copyright (c) 2013 Martin Storsjo
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config.h"
23 #include <float.h>
24 #if HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27 
28 #include "avformat.h"
29 #include "avio_internal.h"
30 #include "internal.h"
31 #include "os_support.h"
32 
33 #include "libavutil/avstring.h"
34 #include "libavutil/base64.h"
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/mathematics.h"
37 #include "libavutil/opt.h"
38 
39 typedef struct Fragment {
40  char file[1024];
41  int64_t start_time, duration;
42  int n;
43 } Fragment;
44 
45 typedef struct OutputStream {
46  int bitrate;
49  int ctx_inited;
50  uint8_t iobuf[32768];
51  char temp_filename[1024];
52  int64_t frag_start_ts, last_ts;
54  int packets_written;
55  int nb_fragments, fragments_size, fragment_index;
57 
58  int has_audio, has_video;
59 
62 
63  uint8_t *extra_packets[2];
64  int extra_packet_sizes[2];
66 } OutputStream;
67 
68 typedef struct HDSContext {
69  const AVClass *class; /* Class for private options. */
74 
77 } HDSContext;
78 
79 static int parse_header(OutputStream *os, const uint8_t *buf, int buf_size)
80 {
81  if (buf_size < 13)
82  return AVERROR_INVALIDDATA;
83  if (memcmp(buf, "FLV", 3))
84  return AVERROR_INVALIDDATA;
85  buf += 13;
86  buf_size -= 13;
87  while (buf_size >= 11 + 4) {
88  int type = buf[0];
89  int size = AV_RB24(&buf[1]) + 11 + 4;
90  if (size > buf_size)
91  return AVERROR_INVALIDDATA;
92  if (type == 8 || type == 9) {
94  return AVERROR_INVALIDDATA;
96  os->extra_packets[os->nb_extra_packets] = av_malloc(size);
97  if (!os->extra_packets[os->nb_extra_packets])
98  return AVERROR(ENOMEM);
99  memcpy(os->extra_packets[os->nb_extra_packets], buf, size);
100  os->nb_extra_packets++;
101  } else if (type == 0x12) {
102  if (os->metadata)
103  return AVERROR_INVALIDDATA;
104  os->metadata_size = size - 11 - 4;
105  os->metadata = av_malloc(os->metadata_size);
106  if (!os->metadata)
107  return AVERROR(ENOMEM);
108  memcpy(os->metadata, buf + 11, os->metadata_size);
109  }
110  buf += size;
111  buf_size -= size;
112  }
113  if (!os->metadata)
114  return AVERROR_INVALIDDATA;
115  return 0;
116 }
117 
118 static int hds_write(void *opaque, uint8_t *buf, int buf_size)
119 {
120  OutputStream *os = opaque;
121  if (os->out) {
122  avio_write(os->out, buf, buf_size);
123  } else {
124  if (!os->metadata_size) {
125  int ret;
126  // Assuming the IO buffer is large enough to fit the
127  // FLV header and all metadata and extradata packets
128  if ((ret = parse_header(os, buf, buf_size)) < 0)
129  return ret;
130  }
131  }
132  return buf_size;
133 }
134 
136 {
137  HDSContext *c = s->priv_data;
138  int i, j;
139  if (!c->streams)
140  return;
141  for (i = 0; i < s->nb_streams; i++) {
142  OutputStream *os = &c->streams[i];
143  if (os->out)
144  ff_format_io_close(s, &os->out);
145  if (os->ctx && os->ctx_inited)
146  av_write_trailer(os->ctx);
147  if (os->ctx)
148  avio_context_free(&os->ctx->pb);
149  if (os->ctx)
151  av_freep(&os->metadata);
152  for (j = 0; j < os->nb_extra_packets; j++)
153  av_freep(&os->extra_packets[j]);
154  for (j = 0; j < os->nb_fragments; j++)
155  av_freep(&os->fragments[j]);
156  av_freep(&os->fragments);
157  }
158  av_freep(&c->streams);
159 }
160 
161 static int write_manifest(AVFormatContext *s, int final)
162 {
163  HDSContext *c = s->priv_data;
164  AVIOContext *out;
165  char filename[1024], temp_filename[1024];
166  int ret, i;
167  double duration = 0;
168 
169  if (c->nb_streams > 0)
170  duration = c->streams[0].last_ts * av_q2d(s->streams[0]->time_base);
171 
172  snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
173  snprintf(temp_filename, sizeof(temp_filename), "%s/index.f4m.tmp", s->url);
174  ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
175  if (ret < 0) {
176  av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
177  return ret;
178  }
179  avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
180  avio_printf(out, "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n");
181  avio_printf(out, "\t<id>%s</id>\n", av_basename(s->url));
182  avio_printf(out, "\t<streamType>%s</streamType>\n",
183  final ? "recorded" : "live");
184  avio_printf(out, "\t<deliveryType>streaming</deliveryType>\n");
185  if (final)
186  avio_printf(out, "\t<duration>%f</duration>\n", duration);
187  for (i = 0; i < c->nb_streams; i++) {
188  OutputStream *os = &c->streams[i];
189  int b64_size = AV_BASE64_SIZE(os->metadata_size);
190  char *base64 = av_malloc(b64_size);
191  if (!base64) {
192  ff_format_io_close(s, &out);
193  return AVERROR(ENOMEM);
194  }
195  av_base64_encode(base64, b64_size, os->metadata, os->metadata_size);
196 
197  avio_printf(out, "\t<bootstrapInfo profile=\"named\" url=\"stream%d.abst\" id=\"bootstrap%d\" />\n", i, i);
198  avio_printf(out, "\t<media bitrate=\"%d\" url=\"stream%d\" bootstrapInfoId=\"bootstrap%d\">\n", os->bitrate/1000, i, i);
199  avio_printf(out, "\t\t<metadata>%s</metadata>\n", base64);
200  avio_printf(out, "\t</media>\n");
201  av_free(base64);
202  }
203  avio_printf(out, "</manifest>\n");
204  avio_flush(out);
205  ff_format_io_close(s, &out);
206  return ff_rename(temp_filename, filename, s);
207 }
208 
209 static void update_size(AVIOContext *out, int64_t pos)
210 {
211  int64_t end = avio_tell(out);
212  avio_seek(out, pos, SEEK_SET);
213  avio_wb32(out, end - pos);
214  avio_seek(out, end, SEEK_SET);
215 }
216 
217 /* Note, the .abst files need to be served with the "binary/octet"
218  * mime type, otherwise at least the OSMF player can easily fail
219  * with "stream not found" when polling for the next fragment. */
220 static int write_abst(AVFormatContext *s, OutputStream *os, int final)
221 {
222  HDSContext *c = s->priv_data;
223  AVIOContext *out;
224  char filename[1024], temp_filename[1024];
225  int i, ret;
226  int64_t asrt_pos, afrt_pos;
227  int start = 0, fragments;
228  int index = s->streams[os->first_stream]->id;
229  int64_t cur_media_time = 0;
230  if (c->window_size)
231  start = FFMAX(os->nb_fragments - c->window_size, 0);
232  fragments = os->nb_fragments - start;
233  if (final)
234  cur_media_time = os->last_ts;
235  else if (os->nb_fragments)
236  cur_media_time = os->fragments[os->nb_fragments - 1]->start_time;
237 
238  snprintf(filename, sizeof(filename),
239  "%s/stream%d.abst", s->url, index);
240  snprintf(temp_filename, sizeof(temp_filename),
241  "%s/stream%d.abst.tmp", s->url, index);
242  ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
243  if (ret < 0) {
244  av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
245  return ret;
246  }
247  avio_wb32(out, 0); // abst size
248  avio_wl32(out, MKTAG('a','b','s','t'));
249  avio_wb32(out, 0); // version + flags
250  avio_wb32(out, os->fragment_index - 1); // BootstrapinfoVersion
251  avio_w8(out, final ? 0 : 0x20); // profile, live, update
252  avio_wb32(out, 1000); // timescale
253  avio_wb64(out, cur_media_time);
254  avio_wb64(out, 0); // SmpteTimeCodeOffset
255  avio_w8(out, 0); // MovieIdentifer (null string)
256  avio_w8(out, 0); // ServerEntryCount
257  avio_w8(out, 0); // QualityEntryCount
258  avio_w8(out, 0); // DrmData (null string)
259  avio_w8(out, 0); // MetaData (null string)
260  avio_w8(out, 1); // SegmentRunTableCount
261  asrt_pos = avio_tell(out);
262  avio_wb32(out, 0); // asrt size
263  avio_wl32(out, MKTAG('a','s','r','t'));
264  avio_wb32(out, 0); // version + flags
265  avio_w8(out, 0); // QualityEntryCount
266  avio_wb32(out, 1); // SegmentRunEntryCount
267  avio_wb32(out, 1); // FirstSegment
268  avio_wb32(out, final ? (os->fragment_index - 1) : 0xffffffff); // FragmentsPerSegment
269  update_size(out, asrt_pos);
270  avio_w8(out, 1); // FragmentRunTableCount
271  afrt_pos = avio_tell(out);
272  avio_wb32(out, 0); // afrt size
273  avio_wl32(out, MKTAG('a','f','r','t'));
274  avio_wb32(out, 0); // version + flags
275  avio_wb32(out, 1000); // timescale
276  avio_w8(out, 0); // QualityEntryCount
277  avio_wb32(out, fragments); // FragmentRunEntryCount
278  for (i = start; i < os->nb_fragments; i++) {
279  avio_wb32(out, os->fragments[i]->n);
280  avio_wb64(out, os->fragments[i]->start_time);
281  avio_wb32(out, os->fragments[i]->duration);
282  }
283  update_size(out, afrt_pos);
284  update_size(out, 0);
285  ff_format_io_close(s, &out);
286  return ff_rename(temp_filename, filename, s);
287 }
288 
289 static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
290 {
291  int ret, i;
292  ret = s->io_open(s, &os->out, os->temp_filename, AVIO_FLAG_WRITE, NULL);
293  if (ret < 0)
294  return ret;
295  avio_wb32(os->out, 0);
296  avio_wl32(os->out, MKTAG('m','d','a','t'));
297  for (i = 0; i < os->nb_extra_packets; i++) {
298  AV_WB24(os->extra_packets[i] + 4, start_ts);
299  os->extra_packets[i][7] = (start_ts >> 24) & 0x7f;
300  avio_write(os->out, os->extra_packets[i], os->extra_packet_sizes[i]);
301  }
302  return 0;
303 }
304 
306 {
307  int64_t pos = avio_tell(os->out);
308  avio_seek(os->out, 0, SEEK_SET);
309  avio_wb32(os->out, pos);
310  avio_flush(os->out);
311  ff_format_io_close(s, &os->out);
312 }
313 
315 {
316  HDSContext *c = s->priv_data;
317  int ret = 0, i;
318  ff_const59 AVOutputFormat *oformat;
319 
320  if (mkdir(s->url, 0777) == -1 && errno != EEXIST) {
321  ret = AVERROR(errno);
322  av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->url);
323  goto fail;
324  }
325 
326  oformat = av_guess_format("flv", NULL, NULL);
327  if (!oformat) {
329  goto fail;
330  }
331 
332  c->streams = av_mallocz_array(s->nb_streams, sizeof(*c->streams));
333  if (!c->streams) {
334  ret = AVERROR(ENOMEM);
335  goto fail;
336  }
337 
338  for (i = 0; i < s->nb_streams; i++) {
339  OutputStream *os = &c->streams[c->nb_streams];
341  AVStream *st = s->streams[i];
342 
343  if (!st->codecpar->bit_rate) {
344  av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i);
345  ret = AVERROR(EINVAL);
346  goto fail;
347  }
348  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
349  if (os->has_video) {
350  c->nb_streams++;
351  os++;
352  }
353  os->has_video = 1;
354  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
355  if (os->has_audio) {
356  c->nb_streams++;
357  os++;
358  }
359  os->has_audio = 1;
360  } else {
361  av_log(s, AV_LOG_ERROR, "Unsupported stream type in stream %d\n", i);
362  ret = AVERROR(EINVAL);
363  goto fail;
364  }
365  os->bitrate += s->streams[i]->codecpar->bit_rate;
366 
367  if (!os->ctx) {
368  os->first_stream = i;
369  ctx = avformat_alloc_context();
370  if (!ctx) {
371  ret = AVERROR(ENOMEM);
372  goto fail;
373  }
374  os->ctx = ctx;
375  ctx->oformat = oformat;
377  ctx->flags = s->flags;
378 
379  ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf),
380  AVIO_FLAG_WRITE, os,
381  NULL, hds_write, NULL);
382  if (!ctx->pb) {
383  ret = AVERROR(ENOMEM);
384  goto fail;
385  }
386  } else {
387  ctx = os->ctx;
388  }
389  s->streams[i]->id = c->nb_streams;
390 
391  if (!(st = avformat_new_stream(ctx, NULL))) {
392  ret = AVERROR(ENOMEM);
393  goto fail;
394  }
396  st->codecpar->codec_tag = 0;
398  st->time_base = s->streams[i]->time_base;
399  }
400  if (c->streams[c->nb_streams].ctx)
401  c->nb_streams++;
402 
403  for (i = 0; i < c->nb_streams; i++) {
404  OutputStream *os = &c->streams[i];
405  int j;
406  if ((ret = avformat_write_header(os->ctx, NULL)) < 0) {
407  goto fail;
408  }
409  os->ctx_inited = 1;
410  avio_flush(os->ctx->pb);
411  for (j = 0; j < os->ctx->nb_streams; j++)
412  s->streams[os->first_stream + j]->time_base = os->ctx->streams[j]->time_base;
413 
414  snprintf(os->temp_filename, sizeof(os->temp_filename),
415  "%s/stream%d_temp", s->url, i);
416  ret = init_file(s, os, 0);
417  if (ret < 0)
418  goto fail;
419 
420  if (!os->has_video && c->min_frag_duration <= 0) {
422  "No video stream in output stream %d and no min frag duration set\n", i);
423  }
424  os->fragment_index = 1;
425  write_abst(s, os, 0);
426  }
427  ret = write_manifest(s, 0);
428 
429 fail:
430  if (ret)
431  hds_free(s);
432  return ret;
433 }
434 
435 static int add_fragment(OutputStream *os, const char *file,
436  int64_t start_time, int64_t duration)
437 {
438  Fragment *frag;
439  if (duration == 0)
440  duration = 1;
441  if (os->nb_fragments >= os->fragments_size) {
442  int ret;
443  os->fragments_size = (os->fragments_size + 1) * 2;
444  if ((ret = av_reallocp_array(&os->fragments, os->fragments_size,
445  sizeof(*os->fragments))) < 0) {
446  os->fragments_size = 0;
447  os->nb_fragments = 0;
448  return ret;
449  }
450  }
451  frag = av_mallocz(sizeof(*frag));
452  if (!frag)
453  return AVERROR(ENOMEM);
454  av_strlcpy(frag->file, file, sizeof(frag->file));
455  frag->start_time = start_time;
456  frag->duration = duration;
457  frag->n = os->fragment_index;
458  os->fragments[os->nb_fragments++] = frag;
459  os->fragment_index++;
460  return 0;
461 }
462 
463 static int hds_flush(AVFormatContext *s, OutputStream *os, int final,
464  int64_t end_ts)
465 {
466  HDSContext *c = s->priv_data;
467  int i, ret = 0;
468  char target_filename[1024];
469  int index = s->streams[os->first_stream]->id;
470 
471  if (!os->packets_written)
472  return 0;
473 
474  avio_flush(os->ctx->pb);
475  os->packets_written = 0;
476  close_file(s, os);
477 
478  snprintf(target_filename, sizeof(target_filename),
479  "%s/stream%dSeg1-Frag%d", s->url, index, os->fragment_index);
480  ret = ff_rename(os->temp_filename, target_filename, s);
481  if (ret < 0)
482  return ret;
483  add_fragment(os, target_filename, os->frag_start_ts, end_ts - os->frag_start_ts);
484 
485  if (!final) {
486  ret = init_file(s, os, end_ts);
487  if (ret < 0)
488  return ret;
489  }
490 
491  if (c->window_size || (final && c->remove_at_exit)) {
492  int remove = os->nb_fragments - c->window_size - c->extra_window_size;
493  if (final && c->remove_at_exit)
494  remove = os->nb_fragments;
495  if (remove > 0) {
496  for (i = 0; i < remove; i++) {
497  unlink(os->fragments[i]->file);
498  av_freep(&os->fragments[i]);
499  }
500  os->nb_fragments -= remove;
501  memmove(os->fragments, os->fragments + remove,
502  os->nb_fragments * sizeof(*os->fragments));
503  }
504  }
505 
506  if (ret >= 0)
507  ret = write_abst(s, os, final);
508  return ret;
509 }
510 
512 {
513  HDSContext *c = s->priv_data;
514  AVStream *st = s->streams[pkt->stream_index];
515  OutputStream *os = &c->streams[s->streams[pkt->stream_index]->id];
516  int64_t end_dts = os->fragment_index * (int64_t)c->min_frag_duration;
517  int ret;
518 
519  if (st->first_dts == AV_NOPTS_VALUE)
520  st->first_dts = pkt->dts;
521 
522  if ((!os->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
523  av_compare_ts(pkt->dts - st->first_dts, st->time_base,
524  end_dts, AV_TIME_BASE_Q) >= 0 &&
525  pkt->flags & AV_PKT_FLAG_KEY && os->packets_written) {
526 
527  if ((ret = hds_flush(s, os, 0, pkt->dts)) < 0)
528  return ret;
529  }
530 
531  // Note, these fragment start timestamps, that represent a whole
532  // OutputStream, assume all streams in it have the same time base.
533  if (!os->packets_written)
534  os->frag_start_ts = pkt->dts;
535  os->last_ts = pkt->dts;
536 
537  os->packets_written++;
538  return ff_write_chained(os->ctx, pkt->stream_index - os->first_stream, pkt, s, 0);
539 }
540 
542 {
543  HDSContext *c = s->priv_data;
544  int i;
545 
546  for (i = 0; i < c->nb_streams; i++)
547  hds_flush(s, &c->streams[i], 1, c->streams[i].last_ts);
548  write_manifest(s, 1);
549 
550  if (c->remove_at_exit) {
551  char filename[1024];
552  snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
553  unlink(filename);
554  for (i = 0; i < c->nb_streams; i++) {
555  snprintf(filename, sizeof(filename), "%s/stream%d.abst", s->url, i);
556  unlink(filename);
557  }
558  rmdir(s->url);
559  }
560 
561  hds_free(s);
562  return 0;
563 }
564 
565 #define OFFSET(x) offsetof(HDSContext, x)
566 #define E AV_OPT_FLAG_ENCODING_PARAM
567 static const AVOption options[] = {
568  { "window_size", "number of fragments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
569  { "extra_window_size", "number of fragments kept outside of the manifest before removing from disk", OFFSET(extra_window_size), AV_OPT_TYPE_INT, { .i64 = 5 }, 0, INT_MAX, E },
570  { "min_frag_duration", "minimum fragment duration (in microseconds)", OFFSET(min_frag_duration), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT_MAX, E },
571  { "remove_at_exit", "remove all fragments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
572  { NULL },
573 };
574 
575 static const AVClass hds_class = {
576  .class_name = "HDS muxer",
577  .item_name = av_default_item_name,
578  .option = options,
579  .version = LIBAVUTIL_VERSION_INT,
580 };
581 
583  .name = "hds",
584  .long_name = NULL_IF_CONFIG_SMALL("HDS Muxer"),
585  .priv_data_size = sizeof(HDSContext),
586  .audio_codec = AV_CODEC_ID_AAC,
587  .video_codec = AV_CODEC_ID_H264,
592  .priv_class = &hds_class,
593 };
int nb_fragments
Definition: hdsenc.c:55
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:689
int(* io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options)
A callback for opening new IO streams.
Definition: avformat.h:1940
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:466
int64_t first_dts
Timestamp corresponding to the last dts sync point.
Definition: avformat.h:1083
#define NULL
Definition: coverity.c:32
Bytestream IO Context.
Definition: avio.h:161
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
uint8_t * metadata
Definition: hdsenc.c:60
static void hds_free(AVFormatContext *s)
Definition: hdsenc.c:135
int64_t start_time
Definition: hdsenc.c:41
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1636
AVOption.
Definition: opt.h:246
static int hds_write_header(AVFormatContext *s)
Definition: hdsenc.c:314
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
int n
Definition: hdsenc.c:42
int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, AVFormatContext *src, int interleave)
Write a packet to another muxer than the one the user originally intended.
Definition: mux.c:1318
int has_audio
Definition: hdsenc.c:58
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:943
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:246
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:675
int64_t last_ts
Definition: hdsenc.c:52
int first_stream
Definition: hdsenc.c:47
GLint GLenum type
Definition: opengl_enc.c:104
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
AVFormatContext * ctx
Definition: dashenc.c:80
uint8_t * extra_packets[2]
Definition: hdsenc.c:63
static AVPacket pkt
AVOutputFormat ff_hds_muxer
Definition: hdsenc.c:582
uint64_t packets_written
Definition: ffmpeg.h:534
static int write_manifest(AVFormatContext *s, int final)
Definition: hdsenc.c:161
int64_t frag_start_ts
Definition: hdsenc.c:52
int nb_streams
Definition: hdsenc.c:76
Format I/O context.
Definition: avformat.h:1358
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
const char * av_basename(const char *path)
Thread safe basename.
Definition: avstring.c:258
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:372
uint8_t
#define av_malloc(s)
int fragment_index
Definition: hdsenc.c:55
AVOptions.
miscellaneous OS support macros and functions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
int id
Format-specific stream ID.
Definition: avformat.h:888
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5647
int ctx_inited
Definition: dashenc.c:81
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4465
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1426
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:144
char temp_filename[1024]
Definition: hdsenc.c:51
uint8_t iobuf[32768]
Definition: hdsenc.c:50
int extra_packet_sizes[2]
Definition: hdsenc.c:64
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1489
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
static const AVClass hds_class
Definition: hdsenc.c:575
ptrdiff_t size
Definition: opengl_enc.c:100
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:218
#define av_log(a,...)
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3986
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
uint8_t iobuf[32768]
Definition: movenc.c:49
#define ff_const59
The ff_const59 define is not part of the public API and will be removed without further warning...
Definition: avformat.h:549
AVIOContext * avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Allocate and initialize an AVIOContext for buffered I/O.
Definition: aviobuf.c:131
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: utils.c:2021
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static int hds_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: hdsenc.c:511
char * url
input or output URL.
Definition: avformat.h:1454
int metadata_size
Definition: hdsenc.c:61
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3953
char * av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size)
Encode data to base64 and null-terminate.
Definition: base64.c:138
#define FFMAX(a, b)
Definition: common.h:94
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:83
#define fail()
Definition: checkasm.h:120
int extra_window_size
Definition: hdsenc.c:71
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
Compare two timestamps each in its own time base.
Definition: mathematics.c:147
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array through a pointer to a pointer.
Definition: mem.c:205
static int hds_write_trailer(AVFormatContext *s)
Definition: hdsenc.c:541
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1414
#define AV_BASE64_SIZE(x)
Calculate the output size needed to base64-encode x bytes to a null-terminated string.
Definition: base64.h:66
av_warn_unused_result int avformat_write_header(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and write the stream header to an output media file.
Definition: mux.c:508
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:94
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:466
#define E
Definition: hdsenc.c:566
const char * name
Definition: avformat.h:505
AVFormatContext * ctx
Definition: movenc.c:48
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
#define s(width, name)
Definition: cbs_vp9.c:257
static void update_size(AVIOContext *out, int64_t pos)
Definition: hdsenc.c:209
static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
Definition: hdsenc.c:289
static int hds_flush(AVFormatContext *s, OutputStream *os, int final, int64_t end_ts)
Definition: hdsenc.c:463
#define FF_ARRAY_ELEMS(a)
ff_const59 struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1377
if(ret)
Stream structure.
Definition: avformat.h:881
int fragments_size
Definition: hdsenc.c:55
static int write_abst(AVFormatContext *s, OutputStream *os, int final)
Definition: hdsenc.c:220
Fragment ** fragments
Definition: hdsenc.c:56
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:87
int min_frag_duration
Definition: hdsenc.c:72
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
AVIOContext * pb
I/O context.
Definition: avformat.h:1400
int window_size
Definition: hdsenc.c:70
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:196
int64_t duration
Definition: hdsenc.c:41
#define OFFSET(x)
Definition: hdsenc.c:565
void * buf
Definition: avisynth_c.h:766
int bitrate
Definition: hdsenc.c:46
static int ff_rename(const char *oldpath, const char *newpath, void *logctx)
Wrap errno on rename() error.
Definition: internal.h:591
Describe the class of an AVClass context structure.
Definition: log.h:67
int index
Definition: gxfenc.c:89
ff_const59 AVOutputFormat * av_guess_format(const char *short_name, const char *filename, const char *mime_type)
Return the output format in the list of registered output formats which best matches the provided par...
Definition: format.c:51
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:238
static int hds_write(void *opaque, uint8_t *buf, int buf_size)
Definition: hdsenc.c:118
#define snprintf
Definition: snprintf.h:34
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4399
#define flags(name, subs,...)
Definition: cbs_av1.c:561
static int add_fragment(OutputStream *os, const char *file, int64_t start_time, int64_t duration)
Definition: hdsenc.c:435
int remove_at_exit
Definition: hdsenc.c:73
Main libavformat public API header.
OutputStream * streams
Definition: hdsenc.c:75
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
void avio_context_free(AVIOContext **s)
Free the supplied IO context and everything associated with it.
Definition: aviobuf.c:148
static int parse_header(OutputStream *os, const uint8_t *buf, int buf_size)
Definition: hdsenc.c:79
#define av_free(p)
void * priv_data
Format private data.
Definition: avformat.h:1386
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:337
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: avcodec.h:1476
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1254
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:380
FILE * out
Definition: movenc.c:54
#define av_freep(p)
void INT64 start
Definition: avisynth_c.h:766
static void close_file(AVFormatContext *s, OutputStream *os)
Definition: hdsenc.c:305
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:60
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1028
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3961
AVIOContext * out
Definition: dashenc.c:82
int stream_index
Definition: avcodec.h:1479
static const AVOption options[]
Definition: hdsenc.c:567
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:910
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
#define MKTAG(a, b, c, d)
Definition: common.h:366
int nb_extra_packets
Definition: hdsenc.c:65
This structure stores compressed data.
Definition: avcodec.h:1454
int has_video
Definition: hdsenc.c:58
char file[1024]
Definition: hdsenc.c:40
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191