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);
150  av_freep(&os->metadata);
151  for (j = 0; j < os->nb_extra_packets; j++)
152  av_freep(&os->extra_packets[j]);
153  for (j = 0; j < os->nb_fragments; j++)
154  av_freep(&os->fragments[j]);
155  av_freep(&os->fragments);
156  }
157  av_freep(&c->streams);
158 }
159 
160 static int write_manifest(AVFormatContext *s, int final)
161 {
162  HDSContext *c = s->priv_data;
163  AVIOContext *out;
164  char filename[1024], temp_filename[1024];
165  int ret, i;
166  double duration = 0;
167 
168  if (c->nb_streams > 0)
169  duration = c->streams[0].last_ts * av_q2d(s->streams[0]->time_base);
170 
171  snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
172  snprintf(temp_filename, sizeof(temp_filename), "%s/index.f4m.tmp", s->url);
173  ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
174  if (ret < 0) {
175  av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
176  return ret;
177  }
178  avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
179  avio_printf(out, "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n");
180  avio_printf(out, "\t<id>%s</id>\n", av_basename(s->url));
181  avio_printf(out, "\t<streamType>%s</streamType>\n",
182  final ? "recorded" : "live");
183  avio_printf(out, "\t<deliveryType>streaming</deliveryType>\n");
184  if (final)
185  avio_printf(out, "\t<duration>%f</duration>\n", duration);
186  for (i = 0; i < c->nb_streams; i++) {
187  OutputStream *os = &c->streams[i];
188  int b64_size = AV_BASE64_SIZE(os->metadata_size);
189  char *base64 = av_malloc(b64_size);
190  if (!base64) {
191  ff_format_io_close(s, &out);
192  return AVERROR(ENOMEM);
193  }
194  av_base64_encode(base64, b64_size, os->metadata, os->metadata_size);
195 
196  avio_printf(out, "\t<bootstrapInfo profile=\"named\" url=\"stream%d.abst\" id=\"bootstrap%d\" />\n", i, i);
197  avio_printf(out, "\t<media bitrate=\"%d\" url=\"stream%d\" bootstrapInfoId=\"bootstrap%d\">\n", os->bitrate/1000, i, i);
198  avio_printf(out, "\t\t<metadata>%s</metadata>\n", base64);
199  avio_printf(out, "\t</media>\n");
200  av_free(base64);
201  }
202  avio_printf(out, "</manifest>\n");
203  avio_flush(out);
204  ff_format_io_close(s, &out);
205  return ff_rename(temp_filename, filename, s);
206 }
207 
208 static void update_size(AVIOContext *out, int64_t pos)
209 {
210  int64_t end = avio_tell(out);
211  avio_seek(out, pos, SEEK_SET);
212  avio_wb32(out, end - pos);
213  avio_seek(out, end, SEEK_SET);
214 }
215 
216 /* Note, the .abst files need to be served with the "binary/octet"
217  * mime type, otherwise at least the OSMF player can easily fail
218  * with "stream not found" when polling for the next fragment. */
219 static int write_abst(AVFormatContext *s, OutputStream *os, int final)
220 {
221  HDSContext *c = s->priv_data;
222  AVIOContext *out;
223  char filename[1024], temp_filename[1024];
224  int i, ret;
225  int64_t asrt_pos, afrt_pos;
226  int start = 0, fragments;
227  int index = s->streams[os->first_stream]->id;
228  int64_t cur_media_time = 0;
229  if (c->window_size)
230  start = FFMAX(os->nb_fragments - c->window_size, 0);
231  fragments = os->nb_fragments - start;
232  if (final)
233  cur_media_time = os->last_ts;
234  else if (os->nb_fragments)
235  cur_media_time = os->fragments[os->nb_fragments - 1]->start_time;
236 
237  snprintf(filename, sizeof(filename),
238  "%s/stream%d.abst", s->url, index);
239  snprintf(temp_filename, sizeof(temp_filename),
240  "%s/stream%d.abst.tmp", s->url, index);
241  ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
242  if (ret < 0) {
243  av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
244  return ret;
245  }
246  avio_wb32(out, 0); // abst size
247  avio_wl32(out, MKTAG('a','b','s','t'));
248  avio_wb32(out, 0); // version + flags
249  avio_wb32(out, os->fragment_index - 1); // BootstrapinfoVersion
250  avio_w8(out, final ? 0 : 0x20); // profile, live, update
251  avio_wb32(out, 1000); // timescale
252  avio_wb64(out, cur_media_time);
253  avio_wb64(out, 0); // SmpteTimeCodeOffset
254  avio_w8(out, 0); // MovieIdentifer (null string)
255  avio_w8(out, 0); // ServerEntryCount
256  avio_w8(out, 0); // QualityEntryCount
257  avio_w8(out, 0); // DrmData (null string)
258  avio_w8(out, 0); // MetaData (null string)
259  avio_w8(out, 1); // SegmentRunTableCount
260  asrt_pos = avio_tell(out);
261  avio_wb32(out, 0); // asrt size
262  avio_wl32(out, MKTAG('a','s','r','t'));
263  avio_wb32(out, 0); // version + flags
264  avio_w8(out, 0); // QualityEntryCount
265  avio_wb32(out, 1); // SegmentRunEntryCount
266  avio_wb32(out, 1); // FirstSegment
267  avio_wb32(out, final ? (os->fragment_index - 1) : 0xffffffff); // FragmentsPerSegment
268  update_size(out, asrt_pos);
269  avio_w8(out, 1); // FragmentRunTableCount
270  afrt_pos = avio_tell(out);
271  avio_wb32(out, 0); // afrt size
272  avio_wl32(out, MKTAG('a','f','r','t'));
273  avio_wb32(out, 0); // version + flags
274  avio_wb32(out, 1000); // timescale
275  avio_w8(out, 0); // QualityEntryCount
276  avio_wb32(out, fragments); // FragmentRunEntryCount
277  for (i = start; i < os->nb_fragments; i++) {
278  avio_wb32(out, os->fragments[i]->n);
279  avio_wb64(out, os->fragments[i]->start_time);
280  avio_wb32(out, os->fragments[i]->duration);
281  }
282  update_size(out, afrt_pos);
283  update_size(out, 0);
284  ff_format_io_close(s, &out);
285  return ff_rename(temp_filename, filename, s);
286 }
287 
288 static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
289 {
290  int ret, i;
291  ret = s->io_open(s, &os->out, os->temp_filename, AVIO_FLAG_WRITE, NULL);
292  if (ret < 0)
293  return ret;
294  avio_wb32(os->out, 0);
295  avio_wl32(os->out, MKTAG('m','d','a','t'));
296  for (i = 0; i < os->nb_extra_packets; i++) {
297  AV_WB24(os->extra_packets[i] + 4, start_ts);
298  os->extra_packets[i][7] = (start_ts >> 24) & 0x7f;
299  avio_write(os->out, os->extra_packets[i], os->extra_packet_sizes[i]);
300  }
301  return 0;
302 }
303 
305 {
306  int64_t pos = avio_tell(os->out);
307  avio_seek(os->out, 0, SEEK_SET);
308  avio_wb32(os->out, pos);
309  avio_flush(os->out);
310  ff_format_io_close(s, &os->out);
311 }
312 
314 {
315  HDSContext *c = s->priv_data;
316  int ret = 0, i;
317  ff_const59 AVOutputFormat *oformat;
318 
319  if (mkdir(s->url, 0777) == -1 && errno != EEXIST) {
320  ret = AVERROR(errno);
321  av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->url);
322  goto fail;
323  }
324 
325  oformat = av_guess_format("flv", NULL, NULL);
326  if (!oformat) {
328  goto fail;
329  }
330 
331  c->streams = av_mallocz_array(s->nb_streams, sizeof(*c->streams));
332  if (!c->streams) {
333  ret = AVERROR(ENOMEM);
334  goto fail;
335  }
336 
337  for (i = 0; i < s->nb_streams; i++) {
338  OutputStream *os = &c->streams[c->nb_streams];
340  AVStream *st = s->streams[i];
341 
342  if (!st->codecpar->bit_rate) {
343  av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i);
344  ret = AVERROR(EINVAL);
345  goto fail;
346  }
347  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
348  if (os->has_video) {
349  c->nb_streams++;
350  os++;
351  }
352  os->has_video = 1;
353  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
354  if (os->has_audio) {
355  c->nb_streams++;
356  os++;
357  }
358  os->has_audio = 1;
359  } else {
360  av_log(s, AV_LOG_ERROR, "Unsupported stream type in stream %d\n", i);
361  ret = AVERROR(EINVAL);
362  goto fail;
363  }
364  os->bitrate += s->streams[i]->codecpar->bit_rate;
365 
366  if (!os->ctx) {
367  os->first_stream = i;
368  ctx = avformat_alloc_context();
369  if (!ctx) {
370  ret = AVERROR(ENOMEM);
371  goto fail;
372  }
373  os->ctx = ctx;
374  ctx->oformat = oformat;
376  ctx->flags = s->flags;
377 
378  ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf),
379  AVIO_FLAG_WRITE, os,
380  NULL, hds_write, NULL);
381  if (!ctx->pb) {
382  ret = AVERROR(ENOMEM);
383  goto fail;
384  }
385  } else {
386  ctx = os->ctx;
387  }
388  s->streams[i]->id = c->nb_streams;
389 
390  if (!(st = avformat_new_stream(ctx, NULL))) {
391  ret = AVERROR(ENOMEM);
392  goto fail;
393  }
395  st->codecpar->codec_tag = 0;
397  st->time_base = s->streams[i]->time_base;
398  }
399  if (c->streams[c->nb_streams].ctx)
400  c->nb_streams++;
401 
402  for (i = 0; i < c->nb_streams; i++) {
403  OutputStream *os = &c->streams[i];
404  int j;
405  if ((ret = avformat_write_header(os->ctx, NULL)) < 0) {
406  goto fail;
407  }
408  os->ctx_inited = 1;
409  avio_flush(os->ctx->pb);
410  for (j = 0; j < os->ctx->nb_streams; j++)
411  s->streams[os->first_stream + j]->time_base = os->ctx->streams[j]->time_base;
412 
413  snprintf(os->temp_filename, sizeof(os->temp_filename),
414  "%s/stream%d_temp", s->url, i);
415  ret = init_file(s, os, 0);
416  if (ret < 0)
417  goto fail;
418 
419  if (!os->has_video && c->min_frag_duration <= 0) {
421  "No video stream in output stream %d and no min frag duration set\n", i);
422  }
423  os->fragment_index = 1;
424  write_abst(s, os, 0);
425  }
426  ret = write_manifest(s, 0);
427 
428 fail:
429  if (ret)
430  hds_free(s);
431  return ret;
432 }
433 
434 static int add_fragment(OutputStream *os, const char *file,
435  int64_t start_time, int64_t duration)
436 {
437  Fragment *frag;
438  if (duration == 0)
439  duration = 1;
440  if (os->nb_fragments >= os->fragments_size) {
441  int ret;
442  os->fragments_size = (os->fragments_size + 1) * 2;
443  if ((ret = av_reallocp_array(&os->fragments, os->fragments_size,
444  sizeof(*os->fragments))) < 0) {
445  os->fragments_size = 0;
446  os->nb_fragments = 0;
447  return ret;
448  }
449  }
450  frag = av_mallocz(sizeof(*frag));
451  if (!frag)
452  return AVERROR(ENOMEM);
453  av_strlcpy(frag->file, file, sizeof(frag->file));
454  frag->start_time = start_time;
455  frag->duration = duration;
456  frag->n = os->fragment_index;
457  os->fragments[os->nb_fragments++] = frag;
458  os->fragment_index++;
459  return 0;
460 }
461 
462 static int hds_flush(AVFormatContext *s, OutputStream *os, int final,
463  int64_t end_ts)
464 {
465  HDSContext *c = s->priv_data;
466  int i, ret = 0;
467  char target_filename[1024];
468  int index = s->streams[os->first_stream]->id;
469 
470  if (!os->packets_written)
471  return 0;
472 
473  avio_flush(os->ctx->pb);
474  os->packets_written = 0;
475  close_file(s, os);
476 
477  snprintf(target_filename, sizeof(target_filename),
478  "%s/stream%dSeg1-Frag%d", s->url, index, os->fragment_index);
479  ret = ff_rename(os->temp_filename, target_filename, s);
480  if (ret < 0)
481  return ret;
482  add_fragment(os, target_filename, os->frag_start_ts, end_ts - os->frag_start_ts);
483 
484  if (!final) {
485  ret = init_file(s, os, end_ts);
486  if (ret < 0)
487  return ret;
488  }
489 
490  if (c->window_size || (final && c->remove_at_exit)) {
491  int remove = os->nb_fragments - c->window_size - c->extra_window_size;
492  if (final && c->remove_at_exit)
493  remove = os->nb_fragments;
494  if (remove > 0) {
495  for (i = 0; i < remove; i++) {
496  unlink(os->fragments[i]->file);
497  av_freep(&os->fragments[i]);
498  }
499  os->nb_fragments -= remove;
500  memmove(os->fragments, os->fragments + remove,
501  os->nb_fragments * sizeof(*os->fragments));
502  }
503  }
504 
505  if (ret >= 0)
506  ret = write_abst(s, os, final);
507  return ret;
508 }
509 
511 {
512  HDSContext *c = s->priv_data;
513  AVStream *st = s->streams[pkt->stream_index];
514  OutputStream *os = &c->streams[s->streams[pkt->stream_index]->id];
515  int64_t end_dts = os->fragment_index * (int64_t)c->min_frag_duration;
516  int ret;
517 
518  if (st->first_dts == AV_NOPTS_VALUE)
519  st->first_dts = pkt->dts;
520 
521  if ((!os->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
522  av_compare_ts(pkt->dts - st->first_dts, st->time_base,
523  end_dts, AV_TIME_BASE_Q) >= 0 &&
524  pkt->flags & AV_PKT_FLAG_KEY && os->packets_written) {
525 
526  if ((ret = hds_flush(s, os, 0, pkt->dts)) < 0)
527  return ret;
528  }
529 
530  // Note, these fragment start timestamps, that represent a whole
531  // OutputStream, assume all streams in it have the same time base.
532  if (!os->packets_written)
533  os->frag_start_ts = pkt->dts;
534  os->last_ts = pkt->dts;
535 
536  os->packets_written++;
537  return ff_write_chained(os->ctx, pkt->stream_index - os->first_stream, pkt, s, 0);
538 }
539 
541 {
542  HDSContext *c = s->priv_data;
543  int i;
544 
545  for (i = 0; i < c->nb_streams; i++)
546  hds_flush(s, &c->streams[i], 1, c->streams[i].last_ts);
547  write_manifest(s, 1);
548 
549  if (c->remove_at_exit) {
550  char filename[1024];
551  snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
552  unlink(filename);
553  for (i = 0; i < c->nb_streams; i++) {
554  snprintf(filename, sizeof(filename), "%s/stream%d.abst", s->url, i);
555  unlink(filename);
556  }
557  rmdir(s->url);
558  }
559 
560  hds_free(s);
561  return 0;
562 }
563 
564 #define OFFSET(x) offsetof(HDSContext, x)
565 #define E AV_OPT_FLAG_ENCODING_PARAM
566 static const AVOption options[] = {
567  { "window_size", "number of fragments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
568  { "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 },
569  { "min_frag_duration", "minimum fragment duration (in microseconds)", OFFSET(min_frag_duration), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT_MAX, E },
570  { "remove_at_exit", "remove all fragments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
571  { NULL },
572 };
573 
574 static const AVClass hds_class = {
575  .class_name = "HDS muxer",
576  .item_name = av_default_item_name,
577  .option = options,
578  .version = LIBAVUTIL_VERSION_INT,
579 };
580 
582  .name = "hds",
583  .long_name = NULL_IF_CONFIG_SMALL("HDS Muxer"),
584  .priv_data_size = sizeof(HDSContext),
585  .audio_codec = AV_CODEC_ID_AAC,
586  .video_codec = AV_CODEC_ID_H264,
591  .priv_class = &hds_class,
592 };
int nb_fragments
Definition: hdsenc.c:55
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:690
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:1939
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:1082
#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:1635
AVOption.
Definition: opt.h:246
static int hds_write_header(AVFormatContext *s)
Definition: hdsenc.c:313
#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:1321
int has_audio
Definition: hdsenc.c:58
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:942
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:99
uint8_t * extra_packets[2]
Definition: hdsenc.c:63
static AVPacket pkt
AVOutputFormat ff_hds_muxer
Definition: hdsenc.c:581
uint64_t packets_written
Definition: ffmpeg.h:534
static int write_manifest(AVFormatContext *s, int final)
Definition: hdsenc.c:160
int64_t frag_start_ts
Definition: hdsenc.c:52
int nb_streams
Definition: hdsenc.c:76
Format I/O context.
Definition: avformat.h:1357
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:887
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5682
int ctx_inited
Definition: dashenc.c:100
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4501
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1425
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:1488
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
static const AVClass hds_class
Definition: hdsenc.c:574
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:4010
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1525
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:2043
#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:510
char * url
input or output URL.
Definition: avformat.h:1453
int metadata_size
Definition: hdsenc.c:61
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3977
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:122
int extra_window_size
Definition: hdsenc.c:71
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1499
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:540
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1413
#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:516
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:565
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:208
static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
Definition: hdsenc.c:288
static int hds_flush(AVFormatContext *s, OutputStream *os, int final, int64_t end_ts)
Definition: hdsenc.c:462
#define FF_ARRAY_ELEMS(a)
ff_const59 struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1376
if(ret)
Stream structure.
Definition: avformat.h:880
int fragments_size
Definition: hdsenc.c:55
static int write_abst(AVFormatContext *s, OutputStream *os, int final)
Definition: hdsenc.c:219
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:1399
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:564
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:589
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:4432
#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:434
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:1385
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:349
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: avcodec.h:1492
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1261
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:304
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:60
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1027
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3985
AVIOContext * out
Definition: dashenc.c:101
int stream_index
Definition: avcodec.h:1495
static const AVOption options[]
Definition: hdsenc.c:566
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:909
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:1470
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