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  av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->url);
321  return AVERROR(errno);
322  }
323 
324  oformat = av_guess_format("flv", NULL, NULL);
325  if (!oformat) {
327  }
328 
329  c->streams = av_mallocz_array(s->nb_streams, sizeof(*c->streams));
330  if (!c->streams) {
331  return AVERROR(ENOMEM);
332  }
333 
334  for (i = 0; i < s->nb_streams; i++) {
335  OutputStream *os = &c->streams[c->nb_streams];
337  AVStream *st = s->streams[i];
338 
339  if (!st->codecpar->bit_rate) {
340  av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i);
341  return AVERROR(EINVAL);
342  }
343  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
344  if (os->has_video) {
345  c->nb_streams++;
346  os++;
347  }
348  os->has_video = 1;
349  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
350  if (os->has_audio) {
351  c->nb_streams++;
352  os++;
353  }
354  os->has_audio = 1;
355  } else {
356  av_log(s, AV_LOG_ERROR, "Unsupported stream type in stream %d\n", i);
357  return AVERROR(EINVAL);
358  }
359  os->bitrate += s->streams[i]->codecpar->bit_rate;
360 
361  if (!os->ctx) {
362  os->first_stream = i;
363  ctx = avformat_alloc_context();
364  if (!ctx) {
365  return AVERROR(ENOMEM);
366  }
367  os->ctx = ctx;
368  ctx->oformat = oformat;
370  ctx->flags = s->flags;
371 
372  ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf),
373  AVIO_FLAG_WRITE, os,
374  NULL, hds_write, NULL);
375  if (!ctx->pb) {
376  return AVERROR(ENOMEM);
377  }
378  } else {
379  ctx = os->ctx;
380  }
381  s->streams[i]->id = c->nb_streams;
382 
383  if (!(st = avformat_new_stream(ctx, NULL))) {
384  return AVERROR(ENOMEM);
385  }
387  st->codecpar->codec_tag = 0;
389  st->time_base = s->streams[i]->time_base;
390  }
391  if (c->streams[c->nb_streams].ctx)
392  c->nb_streams++;
393 
394  for (i = 0; i < c->nb_streams; i++) {
395  OutputStream *os = &c->streams[i];
396  int j;
397  if ((ret = avformat_write_header(os->ctx, NULL)) < 0) {
398  return ret;
399  }
400  os->ctx_inited = 1;
401  avio_flush(os->ctx->pb);
402  for (j = 0; j < os->ctx->nb_streams; j++)
403  s->streams[os->first_stream + j]->time_base = os->ctx->streams[j]->time_base;
404 
405  snprintf(os->temp_filename, sizeof(os->temp_filename),
406  "%s/stream%d_temp", s->url, i);
407  ret = init_file(s, os, 0);
408  if (ret < 0)
409  return ret;
410 
411  if (!os->has_video && c->min_frag_duration <= 0) {
413  "No video stream in output stream %d and no min frag duration set\n", i);
414  }
415  os->fragment_index = 1;
416  write_abst(s, os, 0);
417  }
418  ret = write_manifest(s, 0);
419 
420  return ret;
421 }
422 
423 static int add_fragment(OutputStream *os, const char *file,
424  int64_t start_time, int64_t duration)
425 {
426  Fragment *frag;
427  if (duration == 0)
428  duration = 1;
429  if (os->nb_fragments >= os->fragments_size) {
430  int ret;
431  os->fragments_size = (os->fragments_size + 1) * 2;
432  if ((ret = av_reallocp_array(&os->fragments, os->fragments_size,
433  sizeof(*os->fragments))) < 0) {
434  os->fragments_size = 0;
435  os->nb_fragments = 0;
436  return ret;
437  }
438  }
439  frag = av_mallocz(sizeof(*frag));
440  if (!frag)
441  return AVERROR(ENOMEM);
442  av_strlcpy(frag->file, file, sizeof(frag->file));
443  frag->start_time = start_time;
444  frag->duration = duration;
445  frag->n = os->fragment_index;
446  os->fragments[os->nb_fragments++] = frag;
447  os->fragment_index++;
448  return 0;
449 }
450 
451 static int hds_flush(AVFormatContext *s, OutputStream *os, int final,
452  int64_t end_ts)
453 {
454  HDSContext *c = s->priv_data;
455  int i, ret = 0;
456  char target_filename[1024];
457  int index = s->streams[os->first_stream]->id;
458 
459  if (!os->packets_written)
460  return 0;
461 
462  avio_flush(os->ctx->pb);
463  os->packets_written = 0;
464  close_file(s, os);
465 
466  snprintf(target_filename, sizeof(target_filename),
467  "%s/stream%dSeg1-Frag%d", s->url, index, os->fragment_index);
468  ret = ff_rename(os->temp_filename, target_filename, s);
469  if (ret < 0)
470  return ret;
471  add_fragment(os, target_filename, os->frag_start_ts, end_ts - os->frag_start_ts);
472 
473  if (!final) {
474  ret = init_file(s, os, end_ts);
475  if (ret < 0)
476  return ret;
477  }
478 
479  if (c->window_size || (final && c->remove_at_exit)) {
480  int remove = os->nb_fragments - c->window_size - c->extra_window_size;
481  if (final && c->remove_at_exit)
482  remove = os->nb_fragments;
483  if (remove > 0) {
484  for (i = 0; i < remove; i++) {
485  unlink(os->fragments[i]->file);
486  av_freep(&os->fragments[i]);
487  }
488  os->nb_fragments -= remove;
489  memmove(os->fragments, os->fragments + remove,
490  os->nb_fragments * sizeof(*os->fragments));
491  }
492  }
493 
494  if (ret >= 0)
495  ret = write_abst(s, os, final);
496  return ret;
497 }
498 
500 {
501  HDSContext *c = s->priv_data;
502  AVStream *st = s->streams[pkt->stream_index];
503  OutputStream *os = &c->streams[s->streams[pkt->stream_index]->id];
504  int64_t end_dts = os->fragment_index * (int64_t)c->min_frag_duration;
505  int ret;
506 
507  if (st->first_dts == AV_NOPTS_VALUE)
508  st->first_dts = pkt->dts;
509 
510  if ((!os->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
511  av_compare_ts(pkt->dts - st->first_dts, st->time_base,
512  end_dts, AV_TIME_BASE_Q) >= 0 &&
513  pkt->flags & AV_PKT_FLAG_KEY && os->packets_written) {
514 
515  if ((ret = hds_flush(s, os, 0, pkt->dts)) < 0)
516  return ret;
517  }
518 
519  // Note, these fragment start timestamps, that represent a whole
520  // OutputStream, assume all streams in it have the same time base.
521  if (!os->packets_written)
522  os->frag_start_ts = pkt->dts;
523  os->last_ts = pkt->dts;
524 
525  os->packets_written++;
526  return ff_write_chained(os->ctx, pkt->stream_index - os->first_stream, pkt, s, 0);
527 }
528 
530 {
531  HDSContext *c = s->priv_data;
532  int i;
533 
534  for (i = 0; i < c->nb_streams; i++)
535  hds_flush(s, &c->streams[i], 1, c->streams[i].last_ts);
536  write_manifest(s, 1);
537 
538  if (c->remove_at_exit) {
539  char filename[1024];
540  snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
541  unlink(filename);
542  for (i = 0; i < c->nb_streams; i++) {
543  snprintf(filename, sizeof(filename), "%s/stream%d.abst", s->url, i);
544  unlink(filename);
545  }
546  rmdir(s->url);
547  }
548 
549  return 0;
550 }
551 
552 #define OFFSET(x) offsetof(HDSContext, x)
553 #define E AV_OPT_FLAG_ENCODING_PARAM
554 static const AVOption options[] = {
555  { "window_size", "number of fragments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
556  { "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 },
557  { "min_frag_duration", "minimum fragment duration (in microseconds)", OFFSET(min_frag_duration), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT_MAX, E },
558  { "remove_at_exit", "remove all fragments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
559  { NULL },
560 };
561 
562 static const AVClass hds_class = {
563  .class_name = "HDS muxer",
564  .item_name = av_default_item_name,
565  .option = options,
566  .version = LIBAVUTIL_VERSION_INT,
567 };
568 
570  .name = "hds",
571  .long_name = NULL_IF_CONFIG_SMALL("HDS Muxer"),
572  .priv_data_size = sizeof(HDSContext),
573  .audio_codec = AV_CODEC_ID_AAC,
574  .video_codec = AV_CODEC_ID_H264,
579  .deinit = hds_free,
580  .priv_class = &hds_class,
581 };
int nb_fragments
Definition: hdsenc.c:55
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:701
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:1933
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:453
int64_t first_dts
Timestamp corresponding to the last dts sync point.
Definition: avformat.h:1078
#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:1629
AVOption.
Definition: opt.h:248
static int hds_write_header(AVFormatContext *s)
Definition: hdsenc.c:313
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
#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:1305
int has_audio
Definition: hdsenc.c:58
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:938
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:253
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
#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:237
AVFormatContext * ctx
Definition: dashenc.c:100
uint8_t * extra_packets[2]
Definition: hdsenc.c:63
static AVPacket pkt
AVOutputFormat ff_hds_muxer
Definition: hdsenc.c:569
uint64_t packets_written
Definition: ffmpeg.h:537
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:1351
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:379
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:883
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5685
int ctx_inited
Definition: dashenc.c:101
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4519
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1419
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:208
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:1482
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
static const AVClass hds_class
Definition: hdsenc.c:562
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:225
#define av_log(a,...)
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:89
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:396
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:544
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:138
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:153
static int hds_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: hdsenc.c:499
char * url
input or output URL.
Definition: avformat.h:1447
unsigned int pos
Definition: spdifenc.c:410
int metadata_size
Definition: hdsenc.c:61
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:56
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
int extra_window_size
Definition: hdsenc.c:71
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:369
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:206
static int hds_write_trailer(AVFormatContext *s)
Definition: hdsenc.c:529
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1407
int ff_rename(const char *url_src, const char *url_dst, void *logctx)
Wrap avpriv_io_move and log if error happens.
Definition: avio.c:673
#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:505
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:98
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:461
#define E
Definition: hdsenc.c:553
const char * name
Definition: avformat.h:500
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:451
#define FF_ARRAY_ELEMS(a)
ff_const59 struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1370
if(ret)
Stream structure.
Definition: avformat.h:876
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:1393
int window_size
Definition: hdsenc.c:70
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:203
int64_t duration
Definition: hdsenc.c:41
#define OFFSET(x)
Definition: hdsenc.c:552
int bitrate
Definition: hdsenc.c:46
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:245
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:4448
#define flags(name, subs,...)
Definition: cbs_av1.c:560
static int add_fragment(OutputStream *os, const char *file, int64_t start_time, int64_t duration)
Definition: hdsenc.c:423
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:458
void avio_context_free(AVIOContext **s)
Free the supplied IO context and everything associated with it.
Definition: aviobuf.c:155
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:1379
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:346
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: packet.h:362
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1251
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:387
FILE * out
Definition: movenc.c:54
#define av_freep(p)
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:1023
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:64
AVIOContext * out
Definition: dashenc.c:102
int stream_index
Definition: packet.h:365
static const AVOption options[]
Definition: hdsenc.c:554
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:905
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:406
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: utils.c:2075
int nb_extra_packets
Definition: hdsenc.c:65
This structure stores compressed data.
Definition: packet.h:340
int has_video
Definition: hdsenc.c:58
char file[1024]
Definition: hdsenc.c:40
int i
Definition: input.c:407
#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:190