FFmpeg
hdsenc.c
Go to the documentation of this file.
1 /*
2  * Live HDS fragmenter
3  * Copyright (c) 2013 Martin Storsjo
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config.h"
23 #include <float.h>
24 #if HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27 
28 #include "avformat.h"
29 #include "avio_internal.h"
30 #include "internal.h"
31 #include "os_support.h"
32 
33 #include "libavutil/avstring.h"
34 #include "libavutil/base64.h"
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/mathematics.h"
37 #include "libavutil/opt.h"
38 
39 typedef struct Fragment {
40  char file[1024];
41  int64_t start_time, duration;
42  int n;
43 } Fragment;
44 
45 typedef struct OutputStream {
46  int bitrate;
49  int ctx_inited;
50  uint8_t iobuf[32768];
51  char temp_filename[1024];
54  int packets_written;
57 
59 
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  memcpy(os->extra_packets[os->nb_extra_packets], buf, size);
100  os->nb_extra_packets++;
101  } else if (type == 0x12) {
102  if (os->metadata)
103  return AVERROR_INVALIDDATA;
104  os->metadata_size = size - 11 - 4;
105  os->metadata = av_malloc(os->metadata_size);
106  if (!os->metadata)
107  return AVERROR(ENOMEM);
108  memcpy(os->metadata, buf + 11, os->metadata_size);
109  }
110  buf += size;
111  buf_size -= size;
112  }
113  if (!os->metadata)
114  return AVERROR_INVALIDDATA;
115  return 0;
116 }
117 
118 static int hds_write(void *opaque, uint8_t *buf, int buf_size)
119 {
120  OutputStream *os = opaque;
121  if (os->out) {
122  avio_write(os->out, buf, buf_size);
123  } else {
124  if (!os->metadata_size) {
125  int ret;
126  // Assuming the IO buffer is large enough to fit the
127  // FLV header and all metadata and extradata packets
128  if ((ret = parse_header(os, buf, buf_size)) < 0)
129  return ret;
130  }
131  }
132  return buf_size;
133 }
134 
136 {
137  HDSContext *c = s->priv_data;
138  int i, j;
139  if (!c->streams)
140  return;
141  for (i = 0; i < s->nb_streams; i++) {
142  OutputStream *os = &c->streams[i];
143  if (os->out)
144  ff_format_io_close(s, &os->out);
145  if (os->ctx && os->ctx_inited)
146  av_write_trailer(os->ctx);
147  if (os->ctx)
148  avio_context_free(&os->ctx->pb);
150  av_freep(&os->metadata);
151  for (j = 0; j < os->nb_extra_packets; j++)
152  av_freep(&os->extra_packets[j]);
153  for (j = 0; j < os->nb_fragments; j++)
154  av_freep(&os->fragments[j]);
155  av_freep(&os->fragments);
156  }
157  av_freep(&c->streams);
158 }
159 
160 static int write_manifest(AVFormatContext *s, int final)
161 {
162  HDSContext *c = s->priv_data;
163  AVIOContext *out;
164  char filename[1024], temp_filename[1024];
165  int ret, i;
166  double duration = 0;
167 
168  if (c->nb_streams > 0)
169  duration = c->streams[0].last_ts * av_q2d(s->streams[0]->time_base);
170 
171  snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
172  snprintf(temp_filename, sizeof(temp_filename), "%s/index.f4m.tmp", s->url);
173  ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
174  if (ret < 0) {
175  av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
176  return ret;
177  }
178  avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
179  avio_printf(out, "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n");
180  avio_printf(out, "\t<id>%s</id>\n", av_basename(s->url));
181  avio_printf(out, "\t<streamType>%s</streamType>\n",
182  final ? "recorded" : "live");
183  avio_printf(out, "\t<deliveryType>streaming</deliveryType>\n");
184  if (final)
185  avio_printf(out, "\t<duration>%f</duration>\n", duration);
186  for (i = 0; i < c->nb_streams; i++) {
187  OutputStream *os = &c->streams[i];
188  int b64_size = AV_BASE64_SIZE(os->metadata_size);
189  char *base64 = av_malloc(b64_size);
190  if (!base64) {
192  return AVERROR(ENOMEM);
193  }
194  av_base64_encode(base64, b64_size, os->metadata, os->metadata_size);
195 
196  avio_printf(out, "\t<bootstrapInfo profile=\"named\" url=\"stream%d.abst\" id=\"bootstrap%d\" />\n", i, i);
197  avio_printf(out, "\t<media bitrate=\"%d\" url=\"stream%d\" bootstrapInfoId=\"bootstrap%d\">\n", os->bitrate/1000, i, i);
198  avio_printf(out, "\t\t<metadata>%s</metadata>\n", base64);
199  avio_printf(out, "\t</media>\n");
200  av_free(base64);
201  }
202  avio_printf(out, "</manifest>\n");
203  avio_flush(out);
205  return ff_rename(temp_filename, filename, s);
206 }
207 
208 static void update_size(AVIOContext *out, int64_t pos)
209 {
210  int64_t end = avio_tell(out);
211  avio_seek(out, pos, SEEK_SET);
212  avio_wb32(out, end - pos);
213  avio_seek(out, end, SEEK_SET);
214 }
215 
216 /* Note, the .abst files need to be served with the "binary/octet"
217  * mime type, otherwise at least the OSMF player can easily fail
218  * with "stream not found" when polling for the next fragment. */
219 static int write_abst(AVFormatContext *s, OutputStream *os, int final)
220 {
221  HDSContext *c = s->priv_data;
222  AVIOContext *out;
223  char filename[1024], temp_filename[1024];
224  int i, ret;
225  int64_t asrt_pos, afrt_pos;
226  int start = 0, fragments;
227  int index = s->streams[os->first_stream]->id;
228  int64_t cur_media_time = 0;
229  if (c->window_size)
230  start = FFMAX(os->nb_fragments - c->window_size, 0);
231  fragments = os->nb_fragments - start;
232  if (final)
233  cur_media_time = os->last_ts;
234  else if (os->nb_fragments)
235  cur_media_time = os->fragments[os->nb_fragments - 1]->start_time;
236 
237  snprintf(filename, sizeof(filename),
238  "%s/stream%d.abst", s->url, index);
239  snprintf(temp_filename, sizeof(temp_filename),
240  "%s/stream%d.abst.tmp", s->url, index);
241  ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
242  if (ret < 0) {
243  av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
244  return ret;
245  }
246  avio_wb32(out, 0); // abst size
247  avio_wl32(out, MKTAG('a','b','s','t'));
248  avio_wb32(out, 0); // version + flags
249  avio_wb32(out, os->fragment_index - 1); // BootstrapinfoVersion
250  avio_w8(out, final ? 0 : 0x20); // profile, live, update
251  avio_wb32(out, 1000); // timescale
252  avio_wb64(out, cur_media_time);
253  avio_wb64(out, 0); // SmpteTimeCodeOffset
254  avio_w8(out, 0); // MovieIdentifer (null string)
255  avio_w8(out, 0); // ServerEntryCount
256  avio_w8(out, 0); // QualityEntryCount
257  avio_w8(out, 0); // DrmData (null string)
258  avio_w8(out, 0); // MetaData (null string)
259  avio_w8(out, 1); // SegmentRunTableCount
260  asrt_pos = avio_tell(out);
261  avio_wb32(out, 0); // asrt size
262  avio_wl32(out, MKTAG('a','s','r','t'));
263  avio_wb32(out, 0); // version + flags
264  avio_w8(out, 0); // QualityEntryCount
265  avio_wb32(out, 1); // SegmentRunEntryCount
266  avio_wb32(out, 1); // FirstSegment
267  avio_wb32(out, final ? (os->fragment_index - 1) : 0xffffffff); // FragmentsPerSegment
268  update_size(out, asrt_pos);
269  avio_w8(out, 1); // FragmentRunTableCount
270  afrt_pos = avio_tell(out);
271  avio_wb32(out, 0); // afrt size
272  avio_wl32(out, MKTAG('a','f','r','t'));
273  avio_wb32(out, 0); // version + flags
274  avio_wb32(out, 1000); // timescale
275  avio_w8(out, 0); // QualityEntryCount
276  avio_wb32(out, fragments); // FragmentRunEntryCount
277  for (i = start; i < os->nb_fragments; i++) {
278  avio_wb32(out, os->fragments[i]->n);
280  avio_wb32(out, os->fragments[i]->duration);
281  }
282  update_size(out, afrt_pos);
283  update_size(out, 0);
285  return ff_rename(temp_filename, filename, s);
286 }
287 
288 static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
289 {
290  int ret, i;
291  ret = s->io_open(s, &os->out, os->temp_filename, AVIO_FLAG_WRITE, NULL);
292  if (ret < 0)
293  return ret;
294  avio_wb32(os->out, 0);
295  avio_wl32(os->out, MKTAG('m','d','a','t'));
296  for (i = 0; i < os->nb_extra_packets; i++) {
297  AV_WB24(os->extra_packets[i] + 4, start_ts);
298  os->extra_packets[i][7] = (start_ts >> 24) & 0x7f;
300  }
301  return 0;
302 }
303 
305 {
306  int64_t pos = avio_tell(os->out);
307  avio_seek(os->out, 0, SEEK_SET);
308  avio_wb32(os->out, pos);
309  avio_flush(os->out);
310  ff_format_io_close(s, &os->out);
311 }
312 
314 {
315  HDSContext *c = s->priv_data;
316  const AVOutputFormat *oformat;
317  int ret = 0, i;
318 
319  if (mkdir(s->url, 0777) == -1 && errno != EEXIST) {
320  av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->url);
321  return AVERROR(errno);
322  }
323 
324  oformat = av_guess_format("flv", NULL, NULL);
325  if (!oformat) {
327  }
328 
329  c->streams = av_mallocz_array(s->nb_streams, sizeof(*c->streams));
330  if (!c->streams) {
331  return AVERROR(ENOMEM);
332  }
333 
334  for (i = 0; i < s->nb_streams; i++) {
335  OutputStream *os = &c->streams[c->nb_streams];
337  AVStream *st = s->streams[i];
338 
339  if (!st->codecpar->bit_rate) {
340  av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i);
341  return AVERROR(EINVAL);
342  }
343  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
344  if (os->has_video) {
345  c->nb_streams++;
346  os++;
347  }
348  os->has_video = 1;
349  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
350  if (os->has_audio) {
351  c->nb_streams++;
352  os++;
353  }
354  os->has_audio = 1;
355  } else {
356  av_log(s, AV_LOG_ERROR, "Unsupported stream type in stream %d\n", i);
357  return AVERROR(EINVAL);
358  }
359  os->bitrate += s->streams[i]->codecpar->bit_rate;
360 
361  if (!os->ctx) {
362  os->first_stream = i;
364  if (!ctx) {
365  return AVERROR(ENOMEM);
366  }
367  os->ctx = ctx;
368  ctx->oformat = oformat;
369  ctx->interrupt_callback = s->interrupt_callback;
370  ctx->flags = s->flags;
371 
372  ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf),
373  AVIO_FLAG_WRITE, os,
374  NULL, hds_write, NULL);
375  if (!ctx->pb) {
376  return AVERROR(ENOMEM);
377  }
378  } else {
379  ctx = os->ctx;
380  }
381  s->streams[i]->id = c->nb_streams;
382 
383  if (!(st = avformat_new_stream(ctx, NULL))) {
384  return AVERROR(ENOMEM);
385  }
386  avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar);
387  st->codecpar->codec_tag = 0;
388  st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
389  st->time_base = s->streams[i]->time_base;
390  }
391  if (c->streams[c->nb_streams].ctx)
392  c->nb_streams++;
393 
394  for (i = 0; i < c->nb_streams; i++) {
395  OutputStream *os = &c->streams[i];
396  int j;
397  if ((ret = avformat_write_header(os->ctx, NULL)) < 0) {
398  return ret;
399  }
400  os->ctx_inited = 1;
401  avio_flush(os->ctx->pb);
402  for (j = 0; j < os->ctx->nb_streams; j++)
403  s->streams[os->first_stream + j]->time_base = os->ctx->streams[j]->time_base;
404 
405  snprintf(os->temp_filename, sizeof(os->temp_filename),
406  "%s/stream%d_temp", s->url, i);
407  ret = init_file(s, os, 0);
408  if (ret < 0)
409  return ret;
410 
411  if (!os->has_video && c->min_frag_duration <= 0) {
413  "No video stream in output stream %d and no min frag duration set\n", i);
414  }
415  os->fragment_index = 1;
416  write_abst(s, os, 0);
417  }
418  ret = write_manifest(s, 0);
419 
420  return ret;
421 }
422 
423 static int add_fragment(OutputStream *os, const char *file,
424  int64_t start_time, int64_t duration)
425 {
426  Fragment *frag;
427  if (duration == 0)
428  duration = 1;
429  if (os->nb_fragments >= os->fragments_size) {
430  int ret;
431  os->fragments_size = (os->fragments_size + 1) * 2;
433  sizeof(*os->fragments))) < 0) {
434  os->fragments_size = 0;
435  os->nb_fragments = 0;
436  return ret;
437  }
438  }
439  frag = av_mallocz(sizeof(*frag));
440  if (!frag)
441  return AVERROR(ENOMEM);
442  av_strlcpy(frag->file, file, sizeof(frag->file));
443  frag->start_time = start_time;
444  frag->duration = duration;
445  frag->n = os->fragment_index;
446  os->fragments[os->nb_fragments++] = frag;
447  os->fragment_index++;
448  return 0;
449 }
450 
451 static int hds_flush(AVFormatContext *s, OutputStream *os, int final,
452  int64_t end_ts)
453 {
454  HDSContext *c = s->priv_data;
455  int i, ret = 0;
456  char target_filename[1024];
457  int index = s->streams[os->first_stream]->id;
458 
459  if (!os->packets_written)
460  return 0;
461 
462  avio_flush(os->ctx->pb);
463  os->packets_written = 0;
464  close_file(s, os);
465 
466  snprintf(target_filename, sizeof(target_filename),
467  "%s/stream%dSeg1-Frag%d", s->url, index, os->fragment_index);
468  ret = ff_rename(os->temp_filename, target_filename, s);
469  if (ret < 0)
470  return ret;
471  add_fragment(os, target_filename, os->frag_start_ts, end_ts - os->frag_start_ts);
472 
473  if (!final) {
474  ret = init_file(s, os, end_ts);
475  if (ret < 0)
476  return ret;
477  }
478 
479  if (c->window_size || (final && c->remove_at_exit)) {
480  int remove = os->nb_fragments - c->window_size - c->extra_window_size;
481  if (final && c->remove_at_exit)
482  remove = os->nb_fragments;
483  if (remove > 0) {
484  for (i = 0; i < remove; i++) {
485  unlink(os->fragments[i]->file);
486  av_freep(&os->fragments[i]);
487  }
488  os->nb_fragments -= remove;
489  memmove(os->fragments, os->fragments + remove,
490  os->nb_fragments * sizeof(*os->fragments));
491  }
492  }
493 
494  if (ret >= 0)
495  ret = write_abst(s, os, final);
496  return ret;
497 }
498 
500 {
501  HDSContext *c = s->priv_data;
502  AVStream *st = s->streams[pkt->stream_index];
503  OutputStream *os = &c->streams[s->streams[pkt->stream_index]->id];
504  int64_t end_dts = os->fragment_index * (int64_t)c->min_frag_duration;
505  int ret;
506 
508  st->internal->first_dts = pkt->dts;
509 
510  if ((!os->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
512  end_dts, AV_TIME_BASE_Q) >= 0 &&
514 
515  if ((ret = hds_flush(s, os, 0, pkt->dts)) < 0)
516  return ret;
517  }
518 
519  // Note, these fragment start timestamps, that represent a whole
520  // OutputStream, assume all streams in it have the same time base.
521  if (!os->packets_written)
522  os->frag_start_ts = pkt->dts;
523  os->last_ts = pkt->dts;
524 
525  os->packets_written++;
526  return ff_write_chained(os->ctx, pkt->stream_index - os->first_stream, pkt, s, 0);
527 }
528 
530 {
531  HDSContext *c = s->priv_data;
532  int i;
533 
534  for (i = 0; i < c->nb_streams; i++)
535  hds_flush(s, &c->streams[i], 1, c->streams[i].last_ts);
536  write_manifest(s, 1);
537 
538  if (c->remove_at_exit) {
539  char filename[1024];
540  snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
541  unlink(filename);
542  for (i = 0; i < c->nb_streams; i++) {
543  snprintf(filename, sizeof(filename), "%s/stream%d.abst", s->url, i);
544  unlink(filename);
545  }
546  rmdir(s->url);
547  }
548 
549  return 0;
550 }
551 
552 #define OFFSET(x) offsetof(HDSContext, x)
553 #define E AV_OPT_FLAG_ENCODING_PARAM
554 static const AVOption options[] = {
555  { "window_size", "number of fragments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
556  { "extra_window_size", "number of fragments kept outside of the manifest before removing from disk", OFFSET(extra_window_size), AV_OPT_TYPE_INT, { .i64 = 5 }, 0, INT_MAX, E },
557  { "min_frag_duration", "minimum fragment duration (in microseconds)", OFFSET(min_frag_duration), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT_MAX, E },
558  { "remove_at_exit", "remove all fragments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
559  { NULL },
560 };
561 
562 static const AVClass hds_class = {
563  .class_name = "HDS muxer",
564  .item_name = av_default_item_name,
565  .option = options,
566  .version = LIBAVUTIL_VERSION_INT,
567 };
568 
570  .name = "hds",
571  .long_name = NULL_IF_CONFIG_SMALL("HDS Muxer"),
572  .priv_data_size = sizeof(HDSContext),
573  .audio_codec = AV_CODEC_ID_AAC,
574  .video_codec = AV_CODEC_ID_H264,
579  .deinit = hds_free,
580  .priv_class = &hds_class,
581 };
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:496
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4374
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:56
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:146
out
FILE * out
Definition: movenc.c:54
MKTAG
#define MKTAG(a, b, c, d)
Definition: common.h:478
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:145
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
OutputStream::packets_written
uint64_t packets_written
Definition: ffmpeg.h:551
hds_write_header
static int hds_write_header(AVFormatContext *s)
Definition: hdsenc.c:313
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1175
index
fg index
Definition: ffmpeg_filter.c:168
OutputStream::frag_start_ts
int64_t frag_start_ts
Definition: hdsenc.c:52
AVStream::internal
AVStreamInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1009
AVOption
AVOption.
Definition: opt.h:247
Fragment::start_time
int64_t start_time
Definition: hdsenc.c:41
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:196
float.h
AVStreamInternal::first_dts
int64_t first_dts
Timestamp corresponding to the last dts sync point.
Definition: internal.h:409
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:64
mathematics.h
OutputStream::nb_fragments
int nb_fragments
Definition: hdsenc.c:55
os_support.h
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:404
av_basename
const char * av_basename(const char *path)
Thread safe basename.
Definition: avstring.c:260
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
Fragment
Definition: hdsenc.c:39
hds_free
static void hds_free(AVFormatContext *s)
Definition: hdsenc.c:135
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1374
write_manifest
static int write_manifest(AVFormatContext *s, int final)
Definition: hdsenc.c:160
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:538
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:665
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:75
ff_write_chained
int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, AVFormatContext *src, int interleave)
Write a packet to another muxer than the one the user originally intended.
Definition: mux.c:1291
duration
int64_t duration
Definition: movenc.c:64
OutputStream::first_stream
int first_stream
Definition: hdsenc.c:47
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
OutputStream::has_video
int has_video
Definition: hdsenc.c:58
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1225
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:499
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Definition: opt.h:225
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:656
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
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:469
if
if(ret)
Definition: filter_design.txt:179
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:235
AVFormatContext
Format I/O context.
Definition: avformat.h:1107
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:994
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
ff_hds_muxer
const AVOutputFormat ff_hds_muxer
Definition: hdsenc.c:569
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:870
NULL
#define NULL
Definition: coverity.c:32
OutputStream::ctx_inited
int ctx_inited
Definition: dashenc.c:101
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:98
hds_class
static const AVClass hds_class
Definition: hdsenc.c:562
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1149
HDSContext::extra_window_size
int extra_window_size
Definition: hdsenc.c:71
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:193
base64.h
Fragment::duration
int64_t duration
Definition: hdsenc.c:41
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:1163
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:424
init_file
static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
Definition: hdsenc.c:288
E
#define E
Definition: hdsenc.c:553
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:116
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:166
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:219
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:330
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
update_size
static void update_size(AVIOContext *out, int64_t pos)
Definition: hdsenc.c:208
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:463
AV_WB24
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:903
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:372
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:215
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:373
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array through a pointer to a pointer.
Definition: mem.c:212
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:365
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:379
write_packet
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:729
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:72
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:1237
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
i
int i
Definition: input.c:406
OutputStream::last_ts
int64_t last_ts
Definition: hdsenc.c:52
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:466
AVOutputFormat
Definition: avformat.h:495
avio_internal.h
AVERROR_MUXER_NOT_FOUND
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:60
HDSContext
Definition: hdsenc.c:68
avio_alloc_context
AVIOContext * avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Allocate and initialize an AVIOContext for buffered I/O.
Definition: aviobuf.c:128
OutputStream::ctx
AVFormatContext * ctx
Definition: dashenc.c:100
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:243
hds_write_trailer
static int hds_write_trailer(AVFormatContext *s)
Definition: hdsenc.c:529
add_fragment
static int add_fragment(OutputStream *os, const char *file, int64_t start_time, int64_t duration)
Definition: hdsenc.c:423
close_file
static void close_file(AVFormatContext *s, OutputStream *os)
Definition: hdsenc.c:304
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:847
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:243
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:1126
OutputStream::nb_extra_packets
int nb_extra_packets
Definition: hdsenc.c:65
pos
unsigned int pos
Definition: spdifenc.c:412
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
Definition: opt.h:224
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4301
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:143
hds_flush
static int hds_flush(AVFormatContext *s, OutputStream *os, int final, int64_t end_ts)
Definition: hdsenc.c:451
AVPacket::stream_index
int stream_index
Definition: packet.h:375
OutputStream::out
AVIOContext * out
Definition: dashenc.c:102
avio_wb64
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:439
ff_format_io_close
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5452
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:51
OutputStream::bitrate
int bitrate
Definition: hdsenc.c:46
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:241
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
OFFSET
#define OFFSET(x)
Definition: hdsenc.c:552
OutputStream
Definition: muxing.c:54
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
options
static const AVOption options[]
Definition: hdsenc.c:554
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:83
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:89
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
avstring.h
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:347
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
hds_write
static int hds_write(void *opaque, uint8_t *buf, int buf_size)
Definition: hdsenc.c:118