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 static int hds_write(void *opaque, const uint8_t *buf, int buf_size)
116 {
117  OutputStream *os = opaque;
118  if (os->out) {
119  avio_write(os->out, buf, buf_size);
120  } else {
121  if (!os->metadata_size) {
122  int ret;
123  // Assuming the IO buffer is large enough to fit the
124  // FLV header and all metadata and extradata packets
125  if ((ret = parse_header(os, buf, buf_size)) < 0)
126  return ret;
127  }
128  }
129  return buf_size;
130 }
131 
133 {
134  HDSContext *c = s->priv_data;
135  int i, j;
136  if (!c->streams)
137  return;
138  for (i = 0; i < s->nb_streams; i++) {
139  OutputStream *os = &c->streams[i];
140  if (os->out)
141  ff_format_io_close(s, &os->out);
142  if (os->ctx && os->ctx_inited)
143  av_write_trailer(os->ctx);
144  if (os->ctx)
145  avio_context_free(&os->ctx->pb);
147  av_freep(&os->metadata);
148  for (j = 0; j < os->nb_extra_packets; j++)
149  av_freep(&os->extra_packets[j]);
150  for (j = 0; j < os->nb_fragments; j++)
151  av_freep(&os->fragments[j]);
152  av_freep(&os->fragments);
153  }
154  av_freep(&c->streams);
155 }
156 
157 static int write_manifest(AVFormatContext *s, int final)
158 {
159  HDSContext *c = s->priv_data;
160  AVIOContext *out;
161  char filename[1024], temp_filename[1024];
162  int ret, i;
163  double duration = 0;
164 
165  if (c->nb_streams > 0)
166  duration = c->streams[0].last_ts * av_q2d(s->streams[0]->time_base);
167 
168  snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
169  snprintf(temp_filename, sizeof(temp_filename), "%s/index.f4m.tmp", s->url);
170  ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
171  if (ret < 0) {
172  av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
173  return ret;
174  }
175  avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
176  avio_printf(out, "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n");
177  avio_printf(out, "\t<id>%s</id>\n", av_basename(s->url));
178  avio_printf(out, "\t<streamType>%s</streamType>\n",
179  final ? "recorded" : "live");
180  avio_printf(out, "\t<deliveryType>streaming</deliveryType>\n");
181  if (final)
182  avio_printf(out, "\t<duration>%f</duration>\n", duration);
183  for (i = 0; i < c->nb_streams; i++) {
184  OutputStream *os = &c->streams[i];
185  int b64_size = AV_BASE64_SIZE(os->metadata_size);
186  char *base64 = av_malloc(b64_size);
187  if (!base64) {
189  return AVERROR(ENOMEM);
190  }
191  av_base64_encode(base64, b64_size, os->metadata, os->metadata_size);
192 
193  avio_printf(out, "\t<bootstrapInfo profile=\"named\" url=\"stream%d.abst\" id=\"bootstrap%d\" />\n", i, i);
194  avio_printf(out, "\t<media bitrate=\"%d\" url=\"stream%d\" bootstrapInfoId=\"bootstrap%d\">\n", os->bitrate/1000, i, i);
195  avio_printf(out, "\t\t<metadata>%s</metadata>\n", base64);
196  avio_printf(out, "\t</media>\n");
197  av_free(base64);
198  }
199  avio_printf(out, "</manifest>\n");
200  avio_flush(out);
202  return ff_rename(temp_filename, filename, s);
203 }
204 
205 static void update_size(AVIOContext *out, int64_t pos)
206 {
207  int64_t end = avio_tell(out);
208  avio_seek(out, pos, SEEK_SET);
209  avio_wb32(out, end - pos);
210  avio_seek(out, end, SEEK_SET);
211 }
212 
213 /* Note, the .abst files need to be served with the "binary/octet"
214  * mime type, otherwise at least the OSMF player can easily fail
215  * with "stream not found" when polling for the next fragment. */
216 static int write_abst(AVFormatContext *s, OutputStream *os, int final)
217 {
218  HDSContext *c = s->priv_data;
219  AVIOContext *out;
220  char filename[1024], temp_filename[1024];
221  int i, ret;
222  int64_t asrt_pos, afrt_pos;
223  int start = 0, fragments;
224  int index = s->streams[os->first_stream]->id;
225  int64_t cur_media_time = 0;
226  if (c->window_size)
227  start = FFMAX(os->nb_fragments - c->window_size, 0);
228  fragments = os->nb_fragments - start;
229  if (final)
230  cur_media_time = os->last_ts;
231  else if (os->nb_fragments)
232  cur_media_time = os->fragments[os->nb_fragments - 1]->start_time;
233 
234  snprintf(filename, sizeof(filename),
235  "%s/stream%d.abst", s->url, index);
236  snprintf(temp_filename, sizeof(temp_filename),
237  "%s/stream%d.abst.tmp", s->url, index);
238  ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
239  if (ret < 0) {
240  av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
241  return ret;
242  }
243  avio_wb32(out, 0); // abst size
244  avio_wl32(out, MKTAG('a','b','s','t'));
245  avio_wb32(out, 0); // version + flags
246  avio_wb32(out, os->fragment_index - 1); // BootstrapinfoVersion
247  avio_w8(out, final ? 0 : 0x20); // profile, live, update
248  avio_wb32(out, 1000); // timescale
249  avio_wb64(out, cur_media_time);
250  avio_wb64(out, 0); // SmpteTimeCodeOffset
251  avio_w8(out, 0); // MovieIdentifer (null string)
252  avio_w8(out, 0); // ServerEntryCount
253  avio_w8(out, 0); // QualityEntryCount
254  avio_w8(out, 0); // DrmData (null string)
255  avio_w8(out, 0); // MetaData (null string)
256  avio_w8(out, 1); // SegmentRunTableCount
257  asrt_pos = avio_tell(out);
258  avio_wb32(out, 0); // asrt size
259  avio_wl32(out, MKTAG('a','s','r','t'));
260  avio_wb32(out, 0); // version + flags
261  avio_w8(out, 0); // QualityEntryCount
262  avio_wb32(out, 1); // SegmentRunEntryCount
263  avio_wb32(out, 1); // FirstSegment
264  avio_wb32(out, final ? (os->fragment_index - 1) : 0xffffffff); // FragmentsPerSegment
265  update_size(out, asrt_pos);
266  avio_w8(out, 1); // FragmentRunTableCount
267  afrt_pos = avio_tell(out);
268  avio_wb32(out, 0); // afrt size
269  avio_wl32(out, MKTAG('a','f','r','t'));
270  avio_wb32(out, 0); // version + flags
271  avio_wb32(out, 1000); // timescale
272  avio_w8(out, 0); // QualityEntryCount
273  avio_wb32(out, fragments); // FragmentRunEntryCount
274  for (i = start; i < os->nb_fragments; i++) {
275  avio_wb32(out, os->fragments[i]->n);
277  avio_wb32(out, os->fragments[i]->duration);
278  }
279  update_size(out, afrt_pos);
280  update_size(out, 0);
282  return ff_rename(temp_filename, filename, s);
283 }
284 
285 static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
286 {
287  int ret, i;
288  ret = s->io_open(s, &os->out, os->temp_filename, AVIO_FLAG_WRITE, NULL);
289  if (ret < 0)
290  return ret;
291  avio_wb32(os->out, 0);
292  avio_wl32(os->out, MKTAG('m','d','a','t'));
293  for (i = 0; i < os->nb_extra_packets; i++) {
294  AV_WB24(os->extra_packets[i] + 4, start_ts);
295  os->extra_packets[i][7] = (start_ts >> 24) & 0x7f;
297  }
298  return 0;
299 }
300 
302 {
303  int64_t pos = avio_tell(os->out);
304  avio_seek(os->out, 0, SEEK_SET);
305  avio_wb32(os->out, pos);
306  avio_flush(os->out);
307  ff_format_io_close(s, &os->out);
308 }
309 
311 {
312  HDSContext *c = s->priv_data;
313  const AVOutputFormat *oformat;
314  int ret = 0, i;
315 
316  if (mkdir(s->url, 0777) == -1 && errno != EEXIST) {
317  av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->url);
318  return AVERROR(errno);
319  }
320 
321  oformat = av_guess_format("flv", NULL, NULL);
322  if (!oformat) {
324  }
325 
326  c->streams = av_calloc(s->nb_streams, sizeof(*c->streams));
327  if (!c->streams) {
328  return AVERROR(ENOMEM);
329  }
330 
331  for (i = 0; i < s->nb_streams; i++) {
332  OutputStream *os = &c->streams[c->nb_streams];
334  AVStream *st = s->streams[i];
335 
336  if (!st->codecpar->bit_rate) {
337  av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i);
338  return AVERROR(EINVAL);
339  }
340  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
341  if (os->has_video) {
342  c->nb_streams++;
343  os++;
344  }
345  os->has_video = 1;
346  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
347  if (os->has_audio) {
348  c->nb_streams++;
349  os++;
350  }
351  os->has_audio = 1;
352  } else {
353  av_log(s, AV_LOG_ERROR, "Unsupported stream type in stream %d\n", i);
354  return AVERROR(EINVAL);
355  }
356  os->bitrate += s->streams[i]->codecpar->bit_rate;
357 
358  if (!os->ctx) {
359  os->first_stream = i;
361  if (!ctx) {
362  return AVERROR(ENOMEM);
363  }
364  os->ctx = ctx;
365  ctx->oformat = oformat;
366  ctx->interrupt_callback = s->interrupt_callback;
367  ctx->flags = s->flags;
368 
369  ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf),
370  1, os,
371  NULL, hds_write, NULL);
372  if (!ctx->pb) {
373  return AVERROR(ENOMEM);
374  }
375  } else {
376  ctx = os->ctx;
377  }
378  s->streams[i]->id = c->nb_streams;
379 
380  if (!(st = avformat_new_stream(ctx, NULL))) {
381  return AVERROR(ENOMEM);
382  }
383  avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar);
384  st->codecpar->codec_tag = 0;
385  st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
386  st->time_base = s->streams[i]->time_base;
387  }
388  if (c->streams[c->nb_streams].ctx)
389  c->nb_streams++;
390 
391  for (i = 0; i < c->nb_streams; i++) {
392  OutputStream *os = &c->streams[i];
393  int j;
394  if ((ret = avformat_write_header(os->ctx, NULL)) < 0) {
395  return ret;
396  }
397  os->ctx_inited = 1;
398  avio_flush(os->ctx->pb);
399  for (j = 0; j < os->ctx->nb_streams; j++)
400  s->streams[os->first_stream + j]->time_base = os->ctx->streams[j]->time_base;
401 
402  snprintf(os->temp_filename, sizeof(os->temp_filename),
403  "%s/stream%d_temp", s->url, i);
404  ret = init_file(s, os, 0);
405  if (ret < 0)
406  return ret;
407 
408  if (!os->has_video && c->min_frag_duration <= 0) {
410  "No video stream in output stream %d and no min frag duration set\n", i);
411  }
412  os->fragment_index = 1;
413  write_abst(s, os, 0);
414  }
415  ret = write_manifest(s, 0);
416 
417  return ret;
418 }
419 
420 static int add_fragment(OutputStream *os, const char *file,
421  int64_t start_time, int64_t duration)
422 {
423  Fragment *frag;
424  if (duration == 0)
425  duration = 1;
426  if (os->nb_fragments >= os->fragments_size) {
427  int ret;
428  os->fragments_size = (os->fragments_size + 1) * 2;
430  sizeof(*os->fragments))) < 0) {
431  os->fragments_size = 0;
432  os->nb_fragments = 0;
433  return ret;
434  }
435  }
436  frag = av_mallocz(sizeof(*frag));
437  if (!frag)
438  return AVERROR(ENOMEM);
439  av_strlcpy(frag->file, file, sizeof(frag->file));
440  frag->start_time = start_time;
441  frag->duration = duration;
442  frag->n = os->fragment_index;
443  os->fragments[os->nb_fragments++] = frag;
444  os->fragment_index++;
445  return 0;
446 }
447 
448 static int hds_flush(AVFormatContext *s, OutputStream *os, int final,
449  int64_t end_ts)
450 {
451  HDSContext *c = s->priv_data;
452  int i, ret = 0;
453  char target_filename[1024];
454  int index = s->streams[os->first_stream]->id;
455 
456  if (!os->packets_written)
457  return 0;
458 
459  avio_flush(os->ctx->pb);
460  os->packets_written = 0;
461  close_file(s, os);
462 
463  snprintf(target_filename, sizeof(target_filename),
464  "%s/stream%dSeg1-Frag%d", s->url, index, os->fragment_index);
465  ret = ff_rename(os->temp_filename, target_filename, s);
466  if (ret < 0)
467  return ret;
468  add_fragment(os, target_filename, os->frag_start_ts, end_ts - os->frag_start_ts);
469 
470  if (!final) {
471  ret = init_file(s, os, end_ts);
472  if (ret < 0)
473  return ret;
474  }
475 
476  if (c->window_size || (final && c->remove_at_exit)) {
477  int remove = os->nb_fragments - c->window_size - c->extra_window_size;
478  if (final && c->remove_at_exit)
479  remove = os->nb_fragments;
480  if (remove > 0) {
481  for (i = 0; i < remove; i++) {
482  unlink(os->fragments[i]->file);
483  av_freep(&os->fragments[i]);
484  }
485  os->nb_fragments -= remove;
486  memmove(os->fragments, os->fragments + remove,
487  os->nb_fragments * sizeof(*os->fragments));
488  }
489  }
490 
491  if (ret >= 0)
492  ret = write_abst(s, os, final);
493  return ret;
494 }
495 
497 {
498  HDSContext *c = s->priv_data;
499  AVStream *st = s->streams[pkt->stream_index];
500  FFStream *const sti = ffstream(st);
501  OutputStream *os = &c->streams[s->streams[pkt->stream_index]->id];
502  int64_t end_dts = os->fragment_index * (int64_t)c->min_frag_duration;
503  int ret;
504 
505  if (sti->first_dts == AV_NOPTS_VALUE)
506  sti->first_dts = pkt->dts;
507 
508  if ((!os->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
509  av_compare_ts(pkt->dts - sti->first_dts, st->time_base,
510  end_dts, AV_TIME_BASE_Q) >= 0 &&
512 
513  if ((ret = hds_flush(s, os, 0, pkt->dts)) < 0)
514  return ret;
515  }
516 
517  // Note, these fragment start timestamps, that represent a whole
518  // OutputStream, assume all streams in it have the same time base.
519  if (!os->packets_written)
520  os->frag_start_ts = pkt->dts;
521  os->last_ts = pkt->dts;
522 
523  os->packets_written++;
524  return ff_write_chained(os->ctx, pkt->stream_index - os->first_stream, pkt, s, 0);
525 }
526 
528 {
529  HDSContext *c = s->priv_data;
530  int i;
531 
532  for (i = 0; i < c->nb_streams; i++)
533  hds_flush(s, &c->streams[i], 1, c->streams[i].last_ts);
534  write_manifest(s, 1);
535 
536  if (c->remove_at_exit) {
537  char filename[1024];
538  snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
539  unlink(filename);
540  for (i = 0; i < c->nb_streams; i++) {
541  snprintf(filename, sizeof(filename), "%s/stream%d.abst", s->url, i);
542  unlink(filename);
543  }
544  rmdir(s->url);
545  }
546 
547  return 0;
548 }
549 
550 #define OFFSET(x) offsetof(HDSContext, x)
551 #define E AV_OPT_FLAG_ENCODING_PARAM
552 static const AVOption options[] = {
553  { "window_size", "number of fragments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
554  { "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 },
555  { "min_frag_duration", "minimum fragment duration (in microseconds)", OFFSET(min_frag_duration), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT_MAX, E },
556  { "remove_at_exit", "remove all fragments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
557  { NULL },
558 };
559 
560 static const AVClass hds_class = {
561  .class_name = "HDS muxer",
562  .item_name = av_default_item_name,
563  .option = options,
564  .version = LIBAVUTIL_VERSION_INT,
565 };
566 
568  .p.name = "hds",
569  .p.long_name = NULL_IF_CONFIG_SMALL("HDS Muxer"),
570  .p.audio_codec = AV_CODEC_ID_AAC,
571  .p.video_codec = AV_CODEC_ID_H264,
572  .p.flags = AVFMT_GLOBALHEADER | AVFMT_NOFILE,
573  .p.priv_class = &hds_class,
574  .priv_data_size = sizeof(HDSContext),
578  .deinit = hds_free,
579 };
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:510
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:415
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:125
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:556
hds_write_header
static int hds_write_header(AVFormatContext *s)
Definition: hdsenc.c:310
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1323
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:108
AVOption
AVOption.
Definition: opt.h:346
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:577
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:132
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1528
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:423
write_manifest
static int write_manifest(AVFormatContext *s, int final)
Definition: hdsenc.c:157
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:494
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:860
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:1406
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:496
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Definition: opt.h:236
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:618
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:456
if
if(ret)
Definition: filter_design.txt:179
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:222
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
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:782
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:560
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:1297
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:178
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:1311
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:442
init_file
static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
Definition: hdsenc.c:285
E
#define E
Definition: hdsenc.c:551
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
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:160
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:216
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:329
update_size
static void update_size(AVIOContext *out, int64_t pos)
Definition: hdsenc.c:205
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:468
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:944
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:821
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:521
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:200
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:364
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:356
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:528
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:1270
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:115
OutputStream::last_ts
int64_t last_ts
Definition: hdsenc.c:51
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:478
AVOutputFormat
Definition: avformat.h:509
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:527
ff_hds_muxer
const FFOutputFormat ff_hds_muxer
Definition: hdsenc.c:567
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:209
add_fragment
static int add_fragment(OutputStream *os, const char *file, int64_t start_time, int64_t duration)
Definition: hdsenc.c:420
close_file
static void close_file(AVFormatContext *s, OutputStream *os)
Definition: hdsenc.c:301
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:230
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:1274
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:235
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
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:448
AVPacket::stream_index
int stream_index
Definition: packet.h:524
OutputStream::out
AVIOContext * out
Definition: dashenc.c:108
avio_wb64
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:430
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:80
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:499
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:251
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
OFFSET
#define OFFSET(x)
Definition: hdsenc.c:550
OutputStream
Definition: mux.c:53
options
static const AVOption options[]
Definition: hdsenc.c:552
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:97
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:1369