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 #if HAVE_UNISTD_H
24 #include <unistd.h>
25 #endif
26 
27 #include "avformat.h"
28 #include "internal.h"
29 #include "mux.h"
30 #include "os_support.h"
31 
32 #include "libavutil/avstring.h"
33 #include "libavutil/base64.h"
34 #include "libavutil/intreadwrite.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/opt.h"
37 
38 typedef struct Fragment {
39  char file[1024];
40  int64_t start_time, duration;
41  int n;
42 } Fragment;
43 
44 typedef struct OutputStream {
45  int bitrate;
48  int ctx_inited;
49  uint8_t iobuf[32768];
50  char temp_filename[1024];
53  int packets_written;
56 
58 
59  uint8_t *metadata;
61 
62  uint8_t *extra_packets[2];
65 } OutputStream;
66 
67 typedef struct HDSContext {
68  const AVClass *class; /* Class for private options. */
73 
76 } HDSContext;
77 
78 static int parse_header(OutputStream *os, const uint8_t *buf, int buf_size)
79 {
80  if (buf_size < 13)
81  return AVERROR_INVALIDDATA;
82  if (memcmp(buf, "FLV", 3))
83  return AVERROR_INVALIDDATA;
84  buf += 13;
85  buf_size -= 13;
86  while (buf_size >= 11 + 4) {
87  int type = buf[0];
88  int size = AV_RB24(&buf[1]) + 11 + 4;
89  if (size > buf_size)
90  return AVERROR_INVALIDDATA;
91  if (type == 8 || type == 9) {
93  return AVERROR_INVALIDDATA;
96  if (!os->extra_packets[os->nb_extra_packets])
97  return AVERROR(ENOMEM);
98  os->nb_extra_packets++;
99  } else if (type == 0x12) {
100  if (os->metadata)
101  return AVERROR_INVALIDDATA;
102  os->metadata_size = size - 11 - 4;
103  os->metadata = av_memdup(buf + 11, os->metadata_size);
104  if (!os->metadata)
105  return AVERROR(ENOMEM);
106  }
107  buf += size;
108  buf_size -= size;
109  }
110  if (!os->metadata)
111  return AVERROR_INVALIDDATA;
112  return 0;
113 }
114 
115 #if FF_API_AVIO_WRITE_NONCONST
116 static int hds_write(void *opaque, uint8_t *buf, int buf_size)
117 #else
118 static int hds_write(void *opaque, const uint8_t *buf, int buf_size)
119 #endif
120 {
121  OutputStream *os = opaque;
122  if (os->out) {
123  avio_write(os->out, buf, buf_size);
124  } else {
125  if (!os->metadata_size) {
126  int ret;
127  // Assuming the IO buffer is large enough to fit the
128  // FLV header and all metadata and extradata packets
129  if ((ret = parse_header(os, buf, buf_size)) < 0)
130  return ret;
131  }
132  }
133  return buf_size;
134 }
135 
137 {
138  HDSContext *c = s->priv_data;
139  int i, j;
140  if (!c->streams)
141  return;
142  for (i = 0; i < s->nb_streams; i++) {
143  OutputStream *os = &c->streams[i];
144  if (os->out)
145  ff_format_io_close(s, &os->out);
146  if (os->ctx && os->ctx_inited)
147  av_write_trailer(os->ctx);
148  if (os->ctx)
149  avio_context_free(&os->ctx->pb);
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  const AVOutputFormat *oformat;
318  int ret = 0, i;
319 
320  if (mkdir(s->url, 0777) == -1 && errno != EEXIST) {
321  av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->url);
322  return AVERROR(errno);
323  }
324 
325  oformat = av_guess_format("flv", NULL, NULL);
326  if (!oformat) {
328  }
329 
330  c->streams = av_calloc(s->nb_streams, sizeof(*c->streams));
331  if (!c->streams) {
332  return AVERROR(ENOMEM);
333  }
334 
335  for (i = 0; i < s->nb_streams; i++) {
336  OutputStream *os = &c->streams[c->nb_streams];
338  AVStream *st = s->streams[i];
339 
340  if (!st->codecpar->bit_rate) {
341  av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i);
342  return AVERROR(EINVAL);
343  }
344  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
345  if (os->has_video) {
346  c->nb_streams++;
347  os++;
348  }
349  os->has_video = 1;
350  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
351  if (os->has_audio) {
352  c->nb_streams++;
353  os++;
354  }
355  os->has_audio = 1;
356  } else {
357  av_log(s, AV_LOG_ERROR, "Unsupported stream type in stream %d\n", i);
358  return AVERROR(EINVAL);
359  }
360  os->bitrate += s->streams[i]->codecpar->bit_rate;
361 
362  if (!os->ctx) {
363  os->first_stream = i;
365  if (!ctx) {
366  return AVERROR(ENOMEM);
367  }
368  os->ctx = ctx;
369  ctx->oformat = oformat;
370  ctx->interrupt_callback = s->interrupt_callback;
371  ctx->flags = s->flags;
372 
373  ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf),
374  1, os,
375  NULL, hds_write, NULL);
376  if (!ctx->pb) {
377  return AVERROR(ENOMEM);
378  }
379  } else {
380  ctx = os->ctx;
381  }
382  s->streams[i]->id = c->nb_streams;
383 
384  if (!(st = avformat_new_stream(ctx, NULL))) {
385  return AVERROR(ENOMEM);
386  }
387  avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar);
388  st->codecpar->codec_tag = 0;
389  st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
390  st->time_base = s->streams[i]->time_base;
391  }
392  if (c->streams[c->nb_streams].ctx)
393  c->nb_streams++;
394 
395  for (i = 0; i < c->nb_streams; i++) {
396  OutputStream *os = &c->streams[i];
397  int j;
398  if ((ret = avformat_write_header(os->ctx, NULL)) < 0) {
399  return ret;
400  }
401  os->ctx_inited = 1;
402  avio_flush(os->ctx->pb);
403  for (j = 0; j < os->ctx->nb_streams; j++)
404  s->streams[os->first_stream + j]->time_base = os->ctx->streams[j]->time_base;
405 
406  snprintf(os->temp_filename, sizeof(os->temp_filename),
407  "%s/stream%d_temp", s->url, i);
408  ret = init_file(s, os, 0);
409  if (ret < 0)
410  return ret;
411 
412  if (!os->has_video && c->min_frag_duration <= 0) {
414  "No video stream in output stream %d and no min frag duration set\n", i);
415  }
416  os->fragment_index = 1;
417  write_abst(s, os, 0);
418  }
419  ret = write_manifest(s, 0);
420 
421  return ret;
422 }
423 
424 static int add_fragment(OutputStream *os, const char *file,
425  int64_t start_time, int64_t duration)
426 {
427  Fragment *frag;
428  if (duration == 0)
429  duration = 1;
430  if (os->nb_fragments >= os->fragments_size) {
431  int ret;
432  os->fragments_size = (os->fragments_size + 1) * 2;
434  sizeof(*os->fragments))) < 0) {
435  os->fragments_size = 0;
436  os->nb_fragments = 0;
437  return ret;
438  }
439  }
440  frag = av_mallocz(sizeof(*frag));
441  if (!frag)
442  return AVERROR(ENOMEM);
443  av_strlcpy(frag->file, file, sizeof(frag->file));
444  frag->start_time = start_time;
445  frag->duration = duration;
446  frag->n = os->fragment_index;
447  os->fragments[os->nb_fragments++] = frag;
448  os->fragment_index++;
449  return 0;
450 }
451 
452 static int hds_flush(AVFormatContext *s, OutputStream *os, int final,
453  int64_t end_ts)
454 {
455  HDSContext *c = s->priv_data;
456  int i, ret = 0;
457  char target_filename[1024];
458  int index = s->streams[os->first_stream]->id;
459 
460  if (!os->packets_written)
461  return 0;
462 
463  avio_flush(os->ctx->pb);
464  os->packets_written = 0;
465  close_file(s, os);
466 
467  snprintf(target_filename, sizeof(target_filename),
468  "%s/stream%dSeg1-Frag%d", s->url, index, os->fragment_index);
469  ret = ff_rename(os->temp_filename, target_filename, s);
470  if (ret < 0)
471  return ret;
472  add_fragment(os, target_filename, os->frag_start_ts, end_ts - os->frag_start_ts);
473 
474  if (!final) {
475  ret = init_file(s, os, end_ts);
476  if (ret < 0)
477  return ret;
478  }
479 
480  if (c->window_size || (final && c->remove_at_exit)) {
481  int remove = os->nb_fragments - c->window_size - c->extra_window_size;
482  if (final && c->remove_at_exit)
483  remove = os->nb_fragments;
484  if (remove > 0) {
485  for (i = 0; i < remove; i++) {
486  unlink(os->fragments[i]->file);
487  av_freep(&os->fragments[i]);
488  }
489  os->nb_fragments -= remove;
490  memmove(os->fragments, os->fragments + remove,
491  os->nb_fragments * sizeof(*os->fragments));
492  }
493  }
494 
495  if (ret >= 0)
496  ret = write_abst(s, os, final);
497  return ret;
498 }
499 
501 {
502  HDSContext *c = s->priv_data;
503  AVStream *st = s->streams[pkt->stream_index];
504  FFStream *const sti = ffstream(st);
505  OutputStream *os = &c->streams[s->streams[pkt->stream_index]->id];
506  int64_t end_dts = os->fragment_index * (int64_t)c->min_frag_duration;
507  int ret;
508 
509  if (sti->first_dts == AV_NOPTS_VALUE)
510  sti->first_dts = pkt->dts;
511 
512  if ((!os->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
513  av_compare_ts(pkt->dts - sti->first_dts, st->time_base,
514  end_dts, AV_TIME_BASE_Q) >= 0 &&
516 
517  if ((ret = hds_flush(s, os, 0, pkt->dts)) < 0)
518  return ret;
519  }
520 
521  // Note, these fragment start timestamps, that represent a whole
522  // OutputStream, assume all streams in it have the same time base.
523  if (!os->packets_written)
524  os->frag_start_ts = pkt->dts;
525  os->last_ts = pkt->dts;
526 
527  os->packets_written++;
528  return ff_write_chained(os->ctx, pkt->stream_index - os->first_stream, pkt, s, 0);
529 }
530 
532 {
533  HDSContext *c = s->priv_data;
534  int i;
535 
536  for (i = 0; i < c->nb_streams; i++)
537  hds_flush(s, &c->streams[i], 1, c->streams[i].last_ts);
538  write_manifest(s, 1);
539 
540  if (c->remove_at_exit) {
541  char filename[1024];
542  snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
543  unlink(filename);
544  for (i = 0; i < c->nb_streams; i++) {
545  snprintf(filename, sizeof(filename), "%s/stream%d.abst", s->url, i);
546  unlink(filename);
547  }
548  rmdir(s->url);
549  }
550 
551  return 0;
552 }
553 
554 #define OFFSET(x) offsetof(HDSContext, x)
555 #define E AV_OPT_FLAG_ENCODING_PARAM
556 static const AVOption options[] = {
557  { "window_size", "number of fragments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
558  { "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 },
559  { "min_frag_duration", "minimum fragment duration (in microseconds)", OFFSET(min_frag_duration), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT_MAX, E },
560  { "remove_at_exit", "remove all fragments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
561  { NULL },
562 };
563 
564 static const AVClass hds_class = {
565  .class_name = "HDS muxer",
566  .item_name = av_default_item_name,
567  .option = options,
568  .version = LIBAVUTIL_VERSION_INT,
569 };
570 
572  .p.name = "hds",
573  .p.long_name = NULL_IF_CONFIG_SMALL("HDS Muxer"),
574  .p.audio_codec = AV_CODEC_ID_AAC,
575  .p.video_codec = AV_CODEC_ID_H264,
576  .p.flags = AVFMT_GLOBALHEADER | AVFMT_NOFILE,
577  .p.priv_class = &hds_class,
578  .priv_data_size = sizeof(HDSContext),
582  .deinit = hds_free,
583 };
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVOutputFormat::name
const char * name
Definition: avformat.h:511
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
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
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
FFStream::first_dts
int64_t first_dts
Timestamp corresponding to the last dts sync point.
Definition: internal.h:414
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
OutputStream::fragment_index
int fragment_index
Definition: hdsenc.c:54
avio_context_free
void avio_context_free(AVIOContext **s)
Free the supplied IO context and everything associated with it.
Definition: aviobuf.c:165
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
OutputStream::packets_written
atomic_uint_least64_t packets_written
Definition: ffmpeg.h:594
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:1183
deinit
static void deinit(AVFormatContext *s)
Definition: chromaprint.c:50
OutputStream::frag_start_ts
int64_t frag_start_ts
Definition: hdsenc.c:51
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, const 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:144
AVOption
AVOption.
Definition: opt.h:251
Fragment::start_time
int64_t start_time
Definition: hdsenc.c:40
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
mathematics.h
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
OutputStream::nb_fragments
int nb_fragments
Definition: hdsenc.c:54
os_support.h
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:546
av_basename
const char * av_basename(const char *path)
Thread safe basename.
Definition: avstring.c:252
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:36
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:302
Fragment
Definition: hdsenc.c:38
hds_free
static void hds_free(AVFormatContext *s)
Definition: hdsenc.c:136
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1381
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:420
write_manifest
static int write_manifest(AVFormatContext *s, int final)
Definition: hdsenc.c:161
Fragment::file
char file[1024]
Definition: hdsenc.c:39
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:513
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:75
ff_rename
int ff_rename(const char *url_src, const char *url_dst, void *logctx)
Wrap ffurl_move() and log if error happens.
Definition: avio.c:674
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
HDSContext::streams
OutputStream * streams
Definition: hdsenc.c:74
duration
int64_t duration
Definition: movenc.c:64
OutputStream::first_stream
int first_stream
Definition: hdsenc.c:46
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
OutputStream::has_video
int has_video
Definition: hdsenc.c:57
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1233
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:500
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Definition: opt.h:226
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:637
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
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:477
if
if(ret)
Definition: filter_design.txt:179
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:270
AVFormatContext
Format I/O context.
Definition: avformat.h:1115
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:864
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:880
NULL
#define NULL
Definition: coverity.c:32
OutputStream::ctx_inited
int ctx_inited
Definition: dashenc.c:107
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:101
hds_class
static const AVClass hds_class
Definition: hdsenc.c:564
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1157
HDSContext::extra_window_size
int extra_window_size
Definition: hdsenc.c:70
FFOutputFormat
Definition: mux.h:32
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:226
base64.h
Fragment::duration
int64_t duration
Definition: hdsenc.c:40
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::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1171
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:444
init_file
static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
Definition: hdsenc.c:289
E
#define E
Definition: hdsenc.c:555
AVIOContext
Bytestream IO Context.
Definition: avio.h:166
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:106
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:166
FFStream
Definition: internal.h:199
HDSContext::remove_at_exit
int remove_at_exit
Definition: hdsenc.c:72
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:57
parse_header
static int parse_header(OutputStream *os, const uint8_t *buf, int buf_size)
Definition: hdsenc.c:78
OutputStream::temp_filename
char temp_filename[1024]
Definition: hdsenc.c:50
OutputStream::extra_packet_sizes
int extra_packet_sizes[2]
Definition: hdsenc.c:63
start_time
static int64_t start_time
Definition: ffplay.c:328
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:71
size
int size
Definition: twinvq_data.h:10344
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:62
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:469
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:843
AV_WB24
#define AV_WB24(p, d)
Definition: intreadwrite.h:448
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:919
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:490
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:248
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:412
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:223
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:404
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:497
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:1291
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
hds_write
static int hds_write(void *opaque, const uint8_t *buf, int buf_size)
Definition: hdsenc.c:118
OutputStream::last_ts
int64_t last_ts
Definition: hdsenc.c:51
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:479
AVOutputFormat
Definition: avformat.h:510
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVERROR_MUXER_NOT_FOUND
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:62
HDSContext
Definition: hdsenc.c:67
OutputStream::ctx
AVFormatContext * ctx
Definition: dashenc.c:106
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:254
hds_write_trailer
static int hds_write_trailer(AVFormatContext *s)
Definition: hdsenc.c:531
ff_hds_muxer
const FFOutputFormat ff_hds_muxer
Definition: hdsenc.c:571
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
write_packet
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:61
add_fragment
static int add_fragment(OutputStream *os, const char *file, int64_t start_time, int64_t duration)
Definition: hdsenc.c:424
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:841
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:278
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:71
AVFormatContext::oformat
const struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1134
OutputStream::nb_extra_packets
int nb_extra_packets
Definition: hdsenc.c:64
pos
unsigned int pos
Definition: spdifenc.c:413
avformat.h
OutputStream::fragments_size
int fragments_size
Definition: hdsenc.c:54
OutputStream::fragments
Fragment ** fragments
Definition: hdsenc.c:55
avio_printf
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
OutputStream::iobuf
uint8_t iobuf[32768]
Definition: hdsenc.c:49
OutputStream::metadata_size
int metadata_size
Definition: hdsenc.c:60
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:102
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:145
hds_flush
static int hds_flush(AVFormatContext *s, OutputStream *os, int final, int64_t end_ts)
Definition: hdsenc.c:452
AVPacket::stream_index
int stream_index
Definition: packet.h:493
OutputStream::out
AVIOContext * out
Definition: dashenc.c:108
avio_wb64
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:478
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
av_guess_format
const 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:79
OutputStream::bitrate
int bitrate
Definition: hdsenc.c:45
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVPacket
This structure stores compressed data.
Definition: packet.h:468
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
OFFSET
#define OFFSET(x)
Definition: hdsenc.c:554
OutputStream
Definition: mux.c:53
options
static const AVOption options[]
Definition: hdsenc.c:556
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:85
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:84
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
avstring.h
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:346
HDSContext::window_size
int window_size
Definition: hdsenc.c:69
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:97
OutputStream::metadata
uint8_t * metadata
Definition: hdsenc.c:59
snprintf
#define snprintf
Definition: snprintf.h:34
Fragment::n
int n
Definition: hdsenc.c:41
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
mux.h
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:1390