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