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];
54  int packets_written;
57 
59 
62 
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;
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) {
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);
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);
281  avio_wb32(out, os->fragments[i]->duration);
282  }
283  update_size(out, afrt_pos);
284  update_size(out, 0);
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;
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;
370  if (!ctx) {
371  ret = AVERROR(ENOMEM);
372  goto fail;
373  }
374  os->ctx = ctx;
375  ctx->oformat = oformat;
376  ctx->interrupt_callback = s->interrupt_callback;
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  }
395  avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar);
396  st->codecpar->codec_tag = 0;
397  st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
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;
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) &&
524  end_dts, AV_TIME_BASE_Q) >= 0 &&
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 };
ff_rename
static int ff_rename(const char *oldpath, const char *newpath, void *logctx)
Wrap errno on rename() error.
Definition: internal.h:591
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
AVOutputFormat::name
const char * name
Definition: avformat.h:496
AVERROR
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
opt.h
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4480
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3953
av_compare_ts
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
out
FILE * out
Definition: movenc.c:54
MKTAG
#define MKTAG(a, b, c, d)
Definition: common.h:366
OutputStream::fragment_index
int fragment_index
Definition: hdsenc.c:55
avio_context_free
void avio_context_free(AVIOContext **s)
Free the supplied IO context and everything associated with it.
Definition: aviobuf.c:148
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
ff_hds_muxer
AVOutputFormat ff_hds_muxer
Definition: hdsenc.c:582
OutputStream::packets_written
uint64_t packets_written
Definition: ffmpeg.h:534
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
hds_write_header
static int hds_write_header(AVFormatContext *s)
Definition: hdsenc.c:314
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1410
OutputStream::frag_start_ts
int64_t frag_start_ts
Definition: hdsenc.c:52
AVOption
AVOption.
Definition: opt.h:246
Fragment::start_time
int64_t start_time
Definition: hdsenc.c:41
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191
float.h
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3961
mathematics.h
OutputStream::nb_fragments
int nb_fragments
Definition: hdsenc.c:55
os_support.h
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
av_basename
const char * av_basename(const char *path)
Thread safe basename.
Definition: avstring.c:258
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
ff_const59
#define ff_const59
The ff_const59 define is not part of the public API and will be removed without further warning.
Definition: avformat.h:540
Fragment
Definition: hdsenc.c:39
hds_free
static void hds_free(AVFormatContext *s)
Definition: hdsenc.c:135
av_guess_format
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
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1620
fail
#define fail()
Definition: checkasm.h:120
write_manifest
static int write_manifest(AVFormatContext *s, int final)
Definition: hdsenc.c:161
start
void INT64 start
Definition: avisynth_c.h:767
Fragment::file
char file[1024]
Definition: hdsenc.c:40
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
HDSContext::nb_streams
int nb_streams
Definition: hdsenc.c:76
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
buf
void * buf
Definition: avisynth_c.h:766
AVStream::first_dts
int64_t first_dts
Timestamp corresponding to the last dts sync point.
Definition: avformat.h:1072
HDSContext::streams
OutputStream * streams
Definition: hdsenc.c:75
ff_write_chained
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
duration
int64_t duration
Definition: movenc.c:63
OutputStream::first_stream
int first_stream
Definition: hdsenc.c:47
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
OutputStream::has_video
int has_video
Definition: hdsenc.c:58
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1473
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
hds_write_packet
static int hds_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: hdsenc.c:511
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Definition: opt.h:224
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:655
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: avcodec.h:245
avformat_write_header
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
if
if(ret)
Definition: filter_design.txt:179
AVFormatContext
Format I/O context.
Definition: avformat.h:1342
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1017
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:899
NULL
#define NULL
Definition: coverity.c:32
OutputStream::ctx_inited
int ctx_inited
Definition: dashenc.c:80
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:94
hds_class
static const AVClass hds_class
Definition: hdsenc.c:575
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1384
HDSContext::extra_window_size
int extra_window_size
Definition: hdsenc.c:71
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:196
base64.h
Fragment::duration
int64_t duration
Definition: hdsenc.c:41
index
int index
Definition: gxfenc.c:89
c
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
AVFormatContext::oformat
ff_const59 struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1361
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1398
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: avcodec.h:566
init_file
static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
Definition: hdsenc.c:289
E
#define E
Definition: hdsenc.c:566
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:144
HDSContext::remove_at_exit
int remove_at_exit
Definition: hdsenc.c:73
write_abst
static int write_abst(AVFormatContext *s, OutputStream *os, int final)
Definition: hdsenc.c:220
OutputStream::has_audio
int has_audio
Definition: hdsenc.c:58
parse_header
static int parse_header(OutputStream *os, const uint8_t *buf, int buf_size)
Definition: hdsenc.c:79
OutputStream::temp_filename
char temp_filename[1024]
Definition: hdsenc.c:51
OutputStream::extra_packet_sizes
int extra_packet_sizes[2]
Definition: hdsenc.c:64
start_time
static int64_t start_time
Definition: ffplay.c:331
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
update_size
static void update_size(AVIOContext *out, int64_t pos)
Definition: hdsenc.c:209
HDSContext::min_frag_duration
int min_frag_duration
Definition: hdsenc.c:72
size
int size
Definition: twinvq_data.h:11134
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
OutputStream::extra_packets
uint8_t * extra_packets[2]
Definition: hdsenc.c:63
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
AV_WB24
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:932
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: avcodec.h:1476
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:218
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:377
av_reallocp_array
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
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:369
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
write_packet
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:690
av_write_trailer
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
AV_BASE64_SIZE
#define AV_BASE64_SIZE(x)
Calculate the output size needed to base64-encode x bytes to a null-terminated string.
Definition: base64.h:66
OutputStream::last_ts
int64_t last_ts
Definition: hdsenc.c:52
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:466
AVOutputFormat
Definition: avformat.h:495
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
avio_internal.h
AVERROR_MUXER_NOT_FOUND
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:60
HDSContext
Definition: hdsenc.c:68
avio_alloc_context
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
uint8_t
uint8_t
Definition: audio_convert.c:194
OutputStream::ctx
AVFormatContext * ctx
Definition: dashenc.c:79
av_mallocz
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
hds_write_trailer
static int hds_write_trailer(AVFormatContext *s)
Definition: hdsenc.c:541
add_fragment
static int add_fragment(OutputStream *os, const char *file, int64_t start_time, int64_t duration)
Definition: hdsenc.c:435
close_file
static void close_file(AVFormatContext *s, OutputStream *os)
Definition: hdsenc.c:305
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:870
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:246
AVClass::class_name
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
OutputStream::nb_extra_packets
int nb_extra_packets
Definition: hdsenc.c:65
avformat.h
OutputStream::fragments_size
int fragments_size
Definition: hdsenc.c:55
OutputStream::fragments
Fragment ** fragments
Definition: hdsenc.c:56
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen_template.c:38
avio_printf
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
OutputStream::iobuf
uint8_t iobuf[32768]
Definition: hdsenc.c:50
OutputStream::metadata_size
int metadata_size
Definition: hdsenc.c:61
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
config.h
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4414
av_base64_encode
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
hds_flush
static int hds_flush(AVFormatContext *s, OutputStream *os, int final, int64_t end_ts)
Definition: hdsenc.c:463
AVPacket::stream_index
int stream_index
Definition: avcodec.h:1479
OutputStream::out
AVIOContext * out
Definition: dashenc.c:81
avio_wb64
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:463
ff_format_io_close
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5665
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
OutputStream::bitrate
int bitrate
Definition: hdsenc.c:46
avio_flush
int void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:238
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:240
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
OFFSET
#define OFFSET(x)
Definition: hdsenc.c:565
OutputStream
Definition: muxing.c:53
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
options
static const AVOption options[]
Definition: hdsenc.c:567
av_strlcpy
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
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3986
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
avstring.h
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:337
HDSContext::window_size
int window_size
Definition: hdsenc.c:70
AV_RB24
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:93
OutputStream::metadata
uint8_t * metadata
Definition: hdsenc.c:60
snprintf
#define snprintf
Definition: snprintf.h:34
Fragment::n
int n
Definition: hdsenc.c:42
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: utils.c:2080
hds_write
static int hds_write(void *opaque, uint8_t *buf, int buf_size)
Definition: hdsenc.c:118