ismindex.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Martin Storsjo
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * Libav is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * To create a simple file for smooth streaming:
23  * ffmpeg <normal input/transcoding options> -movflags frag_keyframe foo.ismv
24  * ismindex -n foo foo.ismv
25  * This step creates foo.ism and foo.ismc that is required by IIS for
26  * serving it.
27  *
28  * To pre-split files for serving as static files by a web server without
29  * any extra server support, create the ismv file as above, and split it:
30  * ismindex -split foo.ismv
31  * This step creates a file Manifest and directories QualityLevel(...),
32  * that can be read directly by a smooth streaming player.
33  */
34 
35 #include <stdio.h>
36 #include <string.h>
37 #include <sys/stat.h>
38 #ifdef _WIN32
39 #include <direct.h>
40 #define mkdir(a, b) _mkdir(a)
41 #endif
42 
43 #include "cmdutils.h"
44 
45 #include "libavformat/avformat.h"
46 #include "libavutil/intreadwrite.h"
47 #include "libavutil/mathematics.h"
48 
49 static int usage(const char *argv0, int ret)
50 {
51  fprintf(stderr, "%s [-split] [-n basename] file1 [file2] ...\n", argv0);
52  return ret;
53 }
54 
55 struct MoofOffset {
56  int64_t time;
57  int64_t offset;
58  int duration;
59 };
60 
61 struct Track {
62  const char *name;
63  int64_t duration;
64  int bitrate;
65  int track_id;
66  int is_audio, is_video;
67  int width, height;
68  int chunks;
69  int sample_rate, channels;
73  int timescale;
74  const char *fourcc;
75  int blocksize;
76  int tag;
77 };
78 
79 struct Tracks {
80  int nb_tracks;
81  int64_t duration;
82  struct Track **tracks;
83  int video_track, audio_track;
84  int nb_video_tracks, nb_audio_tracks;
85 };
86 
87 static int copy_tag(AVIOContext *in, AVIOContext *out, int32_t tag_name)
88 {
89  int32_t size, tag;
90 
91  size = avio_rb32(in);
92  tag = avio_rb32(in);
93  avio_wb32(out, size);
94  avio_wb32(out, tag);
95  if (tag != tag_name)
96  return -1;
97  size -= 8;
98  while (size > 0) {
99  char buf[1024];
100  int len = FFMIN(sizeof(buf), size);
101  if (avio_read(in, buf, len) != len)
102  break;
103  avio_write(out, buf, len);
104  size -= len;
105  }
106  return 0;
107 }
108 
109 static int write_fragment(const char *filename, AVIOContext *in)
110 {
111  AVIOContext *out = NULL;
112  int ret;
113 
114  if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, NULL, NULL)) < 0)
115  return ret;
116  copy_tag(in, out, MKBETAG('m', 'o', 'o', 'f'));
117  copy_tag(in, out, MKBETAG('m', 'd', 'a', 't'));
118 
119  avio_flush(out);
120  avio_close(out);
121 
122  return ret;
123 }
124 
125 static int write_fragments(struct Tracks *tracks, int start_index,
126  AVIOContext *in)
127 {
128  char dirname[100], filename[500];
129  int i, j;
130 
131  for (i = start_index; i < tracks->nb_tracks; i++) {
132  struct Track *track = tracks->tracks[i];
133  const char *type = track->is_video ? "video" : "audio";
134  snprintf(dirname, sizeof(dirname), "QualityLevels(%d)", track->bitrate);
135  mkdir(dirname, 0777);
136  for (j = 0; j < track->chunks; j++) {
137  snprintf(filename, sizeof(filename), "%s/Fragments(%s=%"PRId64")",
138  dirname, type, track->offsets[j].time);
139  avio_seek(in, track->offsets[j].offset, SEEK_SET);
140  write_fragment(filename, in);
141  }
142  }
143  return 0;
144 }
145 
146 static int read_tfra(struct Tracks *tracks, int start_index, AVIOContext *f)
147 {
148  int ret = AVERROR_EOF, track_id;
149  int version, fieldlength, i, j;
150  int64_t pos = avio_tell(f);
151  uint32_t size = avio_rb32(f);
152  struct Track *track = NULL;
153 
154  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a'))
155  goto fail;
156  version = avio_r8(f);
157  avio_rb24(f);
158  track_id = avio_rb32(f); /* track id */
159  for (i = start_index; i < tracks->nb_tracks && !track; i++)
160  if (tracks->tracks[i]->track_id == track_id)
161  track = tracks->tracks[i];
162  if (!track) {
163  /* Ok, continue parsing the next atom */
164  ret = 0;
165  goto fail;
166  }
167  fieldlength = avio_rb32(f);
168  track->chunks = avio_rb32(f);
169  track->offsets = av_mallocz(sizeof(*track->offsets) * track->chunks);
170  if (!track->offsets) {
171  ret = AVERROR(ENOMEM);
172  goto fail;
173  }
174  for (i = 0; i < track->chunks; i++) {
175  if (version == 1) {
176  track->offsets[i].time = avio_rb64(f);
177  track->offsets[i].offset = avio_rb64(f);
178  } else {
179  track->offsets[i].time = avio_rb32(f);
180  track->offsets[i].offset = avio_rb32(f);
181  }
182  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
183  avio_r8(f);
184  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
185  avio_r8(f);
186  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
187  avio_r8(f);
188  if (i > 0)
189  track->offsets[i - 1].duration = track->offsets[i].time -
190  track->offsets[i - 1].time;
191  }
192  if (track->chunks > 0)
193  track->offsets[track->chunks - 1].duration = track->duration -
194  track->offsets[track->chunks - 1].time;
195  ret = 0;
196 
197 fail:
198  avio_seek(f, pos + size, SEEK_SET);
199  return ret;
200 }
201 
202 static int read_mfra(struct Tracks *tracks, int start_index,
203  const char *file, int split)
204 {
205  int err = 0;
206  AVIOContext *f = NULL;
207  int32_t mfra_size;
208 
209  if ((err = avio_open2(&f, file, AVIO_FLAG_READ, NULL, NULL)) < 0)
210  goto fail;
211  avio_seek(f, avio_size(f) - 4, SEEK_SET);
212  mfra_size = avio_rb32(f);
213  avio_seek(f, -mfra_size, SEEK_CUR);
214  if (avio_rb32(f) != mfra_size) {
215  err = AVERROR_INVALIDDATA;
216  goto fail;
217  }
218  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
219  err = AVERROR_INVALIDDATA;
220  goto fail;
221  }
222  while (!read_tfra(tracks, start_index, f)) {
223  /* Empty */
224  }
225 
226  if (split)
227  write_fragments(tracks, start_index, f);
228 
229 fail:
230  if (f)
231  avio_close(f);
232  if (err)
233  fprintf(stderr, "Unable to read the MFRA atom in %s\n", file);
234  return err;
235 }
236 
237 static int get_private_data(struct Track *track, AVCodecContext *codec)
238 {
239  track->codec_private_size = codec->extradata_size;
240  track->codec_private = av_mallocz(codec->extradata_size);
241  if (!track->codec_private)
242  return AVERROR(ENOMEM);
243  memcpy(track->codec_private, codec->extradata, codec->extradata_size);
244  return 0;
245 }
246 
248 {
249  AVIOContext *io = NULL;
250  uint16_t sps_size, pps_size;
251  int err = AVERROR(EINVAL);
252 
253  if (codec->codec_id == AV_CODEC_ID_VC1)
254  return get_private_data(track, codec);
255 
256  if (avio_open_dyn_buf(&io) < 0) {
257  err = AVERROR(ENOMEM);
258  goto fail;
259  }
260  if (codec->extradata_size < 11 || codec->extradata[0] != 1)
261  goto fail;
262  sps_size = AV_RB16(&codec->extradata[6]);
263  if (11 + sps_size > codec->extradata_size)
264  goto fail;
265  avio_wb32(io, 0x00000001);
266  avio_write(io, &codec->extradata[8], sps_size);
267  pps_size = AV_RB16(&codec->extradata[9 + sps_size]);
268  if (11 + sps_size + pps_size > codec->extradata_size)
269  goto fail;
270  avio_wb32(io, 0x00000001);
271  avio_write(io, &codec->extradata[11 + sps_size], pps_size);
272  err = 0;
273 
274 fail:
276  return err;
277 }
278 
279 static int handle_file(struct Tracks *tracks, const char *file, int split)
280 {
281  AVFormatContext *ctx = NULL;
282  int err = 0, i, orig_tracks = tracks->nb_tracks;
283  char errbuf[50], *ptr;
284  struct Track *track;
285 
286  err = avformat_open_input(&ctx, file, NULL, NULL);
287  if (err < 0) {
288  av_strerror(err, errbuf, sizeof(errbuf));
289  fprintf(stderr, "Unable to open %s: %s\n", file, errbuf);
290  return 1;
291  }
292 
293  err = avformat_find_stream_info(ctx, NULL);
294  if (err < 0) {
295  av_strerror(err, errbuf, sizeof(errbuf));
296  fprintf(stderr, "Unable to identify %s: %s\n", file, errbuf);
297  goto fail;
298  }
299 
300  if (ctx->nb_streams < 1) {
301  fprintf(stderr, "No streams found in %s\n", file);
302  goto fail;
303  }
304  if (!tracks->duration)
305  tracks->duration = ctx->duration;
306 
307  for (i = 0; i < ctx->nb_streams; i++) {
308  struct Track **temp;
309  AVStream *st = ctx->streams[i];
310  track = av_mallocz(sizeof(*track));
311  if (!track) {
312  err = AVERROR(ENOMEM);
313  goto fail;
314  }
315  temp = av_realloc(tracks->tracks,
316  sizeof(*tracks->tracks) * (tracks->nb_tracks + 1));
317  if (!temp) {
318  av_free(track);
319  err = AVERROR(ENOMEM);
320  goto fail;
321  }
322  tracks->tracks = temp;
323  tracks->tracks[tracks->nb_tracks] = track;
324 
325  track->name = file;
326  if ((ptr = strrchr(file, '/')) != NULL)
327  track->name = ptr + 1;
328 
329  track->bitrate = st->codec->bit_rate;
330  track->track_id = st->id;
331  track->timescale = st->time_base.den;
332  track->duration = av_rescale_rnd(ctx->duration, track->timescale,
334  track->is_audio = st->codec->codec_type == AVMEDIA_TYPE_AUDIO;
335  track->is_video = st->codec->codec_type == AVMEDIA_TYPE_VIDEO;
336 
337  if (!track->is_audio && !track->is_video) {
338  fprintf(stderr,
339  "Track %d in %s is neither video nor audio, skipping\n",
340  track->track_id, file);
341  av_freep(&tracks->tracks[tracks->nb_tracks]);
342  continue;
343  }
344 
345  if (track->is_audio) {
346  if (tracks->audio_track < 0)
347  tracks->audio_track = tracks->nb_tracks;
348  tracks->nb_audio_tracks++;
349  track->channels = st->codec->channels;
350  track->sample_rate = st->codec->sample_rate;
351  if (st->codec->codec_id == AV_CODEC_ID_AAC) {
352  track->fourcc = "AACL";
353  track->tag = 255;
354  track->blocksize = 4;
355  } else if (st->codec->codec_id == AV_CODEC_ID_WMAPRO) {
356  track->fourcc = "WMAP";
357  track->tag = st->codec->codec_tag;
358  track->blocksize = st->codec->block_align;
359  }
360  get_private_data(track, st->codec);
361  }
362  if (track->is_video) {
363  if (tracks->video_track < 0)
364  tracks->video_track = tracks->nb_tracks;
365  tracks->nb_video_tracks++;
366  track->width = st->codec->width;
367  track->height = st->codec->height;
368  if (st->codec->codec_id == AV_CODEC_ID_H264)
369  track->fourcc = "H264";
370  else if (st->codec->codec_id == AV_CODEC_ID_VC1)
371  track->fourcc = "WVC1";
372  get_video_private_data(track, st->codec);
373  }
374 
375  tracks->nb_tracks++;
376  }
377 
378  avformat_close_input(&ctx);
379 
380  err = read_mfra(tracks, orig_tracks, file, split);
381 
382 fail:
383  if (ctx)
384  avformat_close_input(&ctx);
385  return err;
386 }
387 
388 static void output_server_manifest(struct Tracks *tracks,
389  const char *basename)
390 {
391  char filename[1000];
392  FILE *out;
393  int i;
394 
395  snprintf(filename, sizeof(filename), "%s.ism", basename);
396  out = fopen(filename, "w");
397  if (!out) {
398  perror(filename);
399  return;
400  }
401  fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
402  fprintf(out, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
403  fprintf(out, "\t<head>\n");
404  fprintf(out, "\t\t<meta name=\"clientManifestRelativePath\" "
405  "content=\"%s.ismc\" />\n", basename);
406  fprintf(out, "\t</head>\n");
407  fprintf(out, "\t<body>\n");
408  fprintf(out, "\t\t<switch>\n");
409  for (i = 0; i < tracks->nb_tracks; i++) {
410  struct Track *track = tracks->tracks[i];
411  const char *type = track->is_video ? "video" : "audio";
412  fprintf(out, "\t\t\t<%s src=\"%s\" systemBitrate=\"%d\">\n",
413  type, track->name, track->bitrate);
414  fprintf(out, "\t\t\t\t<param name=\"trackID\" value=\"%d\" "
415  "valueType=\"data\" />\n", track->track_id);
416  fprintf(out, "\t\t\t</%s>\n", type);
417  }
418  fprintf(out, "\t\t</switch>\n");
419  fprintf(out, "\t</body>\n");
420  fprintf(out, "</smil>\n");
421  fclose(out);
422 }
423 
424 static void print_track_chunks(FILE *out, struct Tracks *tracks, int main,
425  const char *type)
426 {
427  int i, j;
428  struct Track *track = tracks->tracks[main];
429  for (i = 0; i < track->chunks; i++) {
430  for (j = main + 1; j < tracks->nb_tracks; j++) {
431  if (tracks->tracks[j]->is_audio == track->is_audio &&
432  track->offsets[i].duration != tracks->tracks[j]->offsets[i].duration)
433  fprintf(stderr, "Mismatched duration of %s chunk %d in %s and %s\n",
434  type, i, track->name, tracks->tracks[j]->name);
435  }
436  fprintf(out, "\t\t<c n=\"%d\" d=\"%d\" />\n",
437  i, track->offsets[i].duration);
438  }
439 }
440 
441 static void output_client_manifest(struct Tracks *tracks,
442  const char *basename, int split)
443 {
444  char filename[1000];
445  FILE *out;
446  int i, j;
447 
448  if (split)
449  snprintf(filename, sizeof(filename), "Manifest");
450  else
451  snprintf(filename, sizeof(filename), "%s.ismc", basename);
452  out = fopen(filename, "w");
453  if (!out) {
454  perror(filename);
455  return;
456  }
457  fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
458  fprintf(out, "<SmoothStreamingMedia MajorVersion=\"2\" MinorVersion=\"0\" "
459  "Duration=\"%"PRId64 "\">\n", tracks->duration * 10);
460  if (tracks->video_track >= 0) {
461  struct Track *track = tracks->tracks[tracks->video_track];
462  struct Track *first_track = track;
463  int index = 0;
464  fprintf(out,
465  "\t<StreamIndex Type=\"video\" QualityLevels=\"%d\" "
466  "Chunks=\"%d\" "
467  "Url=\"QualityLevels({bitrate})/Fragments(video={start time})\">\n",
468  tracks->nb_video_tracks, track->chunks);
469  for (i = 0; i < tracks->nb_tracks; i++) {
470  track = tracks->tracks[i];
471  if (!track->is_video)
472  continue;
473  fprintf(out,
474  "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
475  "FourCC=\"%s\" MaxWidth=\"%d\" MaxHeight=\"%d\" "
476  "CodecPrivateData=\"",
477  index, track->bitrate, track->fourcc, track->width, track->height);
478  for (j = 0; j < track->codec_private_size; j++)
479  fprintf(out, "%02X", track->codec_private[j]);
480  fprintf(out, "\" />\n");
481  index++;
482  if (track->chunks != first_track->chunks)
483  fprintf(stderr, "Mismatched number of video chunks in %s and %s\n",
484  track->name, first_track->name);
485  }
486  print_track_chunks(out, tracks, tracks->video_track, "video");
487  fprintf(out, "\t</StreamIndex>\n");
488  }
489  if (tracks->audio_track >= 0) {
490  struct Track *track = tracks->tracks[tracks->audio_track];
491  struct Track *first_track = track;
492  int index = 0;
493  fprintf(out,
494  "\t<StreamIndex Type=\"audio\" QualityLevels=\"%d\" "
495  "Chunks=\"%d\" "
496  "Url=\"QualityLevels({bitrate})/Fragments(audio={start time})\">\n",
497  tracks->nb_audio_tracks, track->chunks);
498  for (i = 0; i < tracks->nb_tracks; i++) {
499  track = tracks->tracks[i];
500  if (!track->is_audio)
501  continue;
502  fprintf(out,
503  "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
504  "FourCC=\"%s\" SamplingRate=\"%d\" Channels=\"%d\" "
505  "BitsPerSample=\"16\" PacketSize=\"%d\" "
506  "AudioTag=\"%d\" CodecPrivateData=\"",
507  index, track->bitrate, track->fourcc, track->sample_rate,
508  track->channels, track->blocksize, track->tag);
509  for (j = 0; j < track->codec_private_size; j++)
510  fprintf(out, "%02X", track->codec_private[j]);
511  fprintf(out, "\" />\n");
512  index++;
513  if (track->chunks != first_track->chunks)
514  fprintf(stderr, "Mismatched number of audio chunks in %s and %s\n",
515  track->name, first_track->name);
516  }
517  print_track_chunks(out, tracks, tracks->audio_track, "audio");
518  fprintf(out, "\t</StreamIndex>\n");
519  }
520  fprintf(out, "</SmoothStreamingMedia>\n");
521  fclose(out);
522 }
523 
524 static void clean_tracks(struct Tracks *tracks)
525 {
526  int i;
527  for (i = 0; i < tracks->nb_tracks; i++) {
528  av_freep(&tracks->tracks[i]->codec_private);
529  av_freep(&tracks->tracks[i]->offsets);
530  av_freep(&tracks->tracks[i]);
531  }
532  av_freep(&tracks->tracks);
533  tracks->nb_tracks = 0;
534 }
535 
536 int main(int argc, char **argv)
537 {
538  const char *basename = NULL;
539  int split = 0, i;
540  struct Tracks tracks = { 0, .video_track = -1, .audio_track = -1 };
541 
542  av_register_all();
543 
544  for (i = 1; i < argc; i++) {
545  if (!strcmp(argv[i], "-n")) {
546  basename = argv[i + 1];
547  i++;
548  } else if (!strcmp(argv[i], "-split")) {
549  split = 1;
550  } else if (argv[i][0] == '-') {
551  return usage(argv[0], 1);
552  } else {
553  if (handle_file(&tracks, argv[i], split))
554  return 1;
555  }
556  }
557  if (!tracks.nb_tracks || (!basename && !split))
558  return usage(argv[0], 1);
559 
560  if (!split)
561  output_server_manifest(&tracks, basename);
562  output_client_manifest(&tracks, basename, split);
563 
564  clean_tracks(&tracks);
565 
566  return 0;
567 }
static int copy_tag(AVIOContext *in, AVIOContext *out, int32_t tag_name)
Definition: ismindex.c:87
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
Bytestream IO Context.
Definition: avio.h:68
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:261
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:988
static int usage(const char *argv0, int ret)
Definition: ismindex.c:49
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:60
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
else temp
Definition: vf_mcdeint.c:148
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:199
#define AVIO_FLAG_READ
read-only
Definition: avio.h:332
Sinusoidal phase f
About Git write you should know how to use GIT properly Luckily Git comes with excellent documentation git help man git shows you the available git< command > help man git< command > shows information about the subcommand< command > The most comprehensive manual is the website Git Reference visit they are quite exhaustive You do not need a special username or password All you need is to provide a ssh public key to the Git server admin What follows now is a basic introduction to Git and some FFmpeg specific guidelines Read it at least if you are granted commit privileges to the FFmpeg project you are expected to be familiar with these rules I if not You can get git from etc no matter how small Every one of them has been saved from looking like a fool by this many times It s very easy for stray debug output or cosmetic modifications to slip in
Definition: git-howto.txt:5
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:333
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:141
int version
Definition: avisynth_c.h:666
int is_audio
Definition: ismindex.c:66
static void print_track_chunks(FILE *out, struct Tracks *tracks, int main, const char *type)
Definition: ismindex.c:424
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:976
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs...
int tag
Definition: ismindex.c:76
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
int height
Definition: ismindex.c:67
Format I/O context.
Definition: avformat.h:944
static int write_fragments(struct Tracks *tracks, int start_index, AVIOContext *in)
Definition: ismindex.c:125
uint8_t
Round toward +infinity.
Definition: mathematics.h:71
struct MoofOffset * offsets
Definition: ismindex.c:72
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:610
int id
Format-specific stream ID.
Definition: avformat.h:650
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
int bitrate
Definition: ismindex.c:64
int nb_tracks
Definition: ismindex.c:80
AVStream ** streams
Definition: avformat.h:992
uint32_t tag
Definition: movenc.c:894
#define AVERROR_EOF
End of file.
Definition: error.h:55
Definition: ismindex.c:61
int64_t time
Definition: ismindex.c:56
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:675
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:248
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:173
static int write_fragment(const char *filename, AVIOContext *in)
Definition: ismindex.c:109
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:478
int width
Definition: ismindex.c:67
int is_video
Definition: ismindex.c:66
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
int channels
Definition: ismindex.c:69
#define AV_RB16
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: aviobuf.c:821
int sample_rate
Definition: ismindex.c:69
int64_t duration
Definition: ismindex.c:81
int size
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:469
const char * fourcc
Definition: ismindex.c:74
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
static int read_mfra(struct Tracks *tracks, int start_index, const char *file, int split)
Definition: ismindex.c:202
unsigned int nb_streams
A list of all streams in the file.
Definition: avformat.h:991
int bit_rate
the average bitrate
int void avio_flush(AVIOContext *s)
Force flushing of buffered data to the output s.
Definition: aviobuf.c:193
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:603
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:196
#define FFMIN(a, b)
Definition: common.h:58
ret
Definition: avfilter.c:821
int width
picture width / height.
FFmpeg Automated Testing Environment ************************************Table of Contents *****************FFmpeg Automated Testing Environment Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass target exec to configure or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script tests fate sh from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at doc fate_config sh template Create a configuration that suits your based on the configuration template The slot configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern< arch >< os >< compiler >< compiler version > The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the fate_recv variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration file
Definition: fate.txt:34
int chunks
Definition: ismindex.c:68
static void output_client_manifest(struct Tracks *tracks, const char *basename, int split)
Definition: ismindex.c:441
int32_t
int audio_track
Definition: ismindex.c:83
static void output_server_manifest(struct Tracks *tracks, const char *basename)
Definition: ismindex.c:388
Note except for filters that can have queued request_frame does not push and as a the filter_frame method will be called and do the work Legacy the filter_frame method was split
Stream structure.
Definition: avformat.h:643
NULL
Definition: eval.c:55
enum AVMediaType codec_type
enum AVCodecID codec_id
int sample_rate
samples per second
Close file fclose(fid)
int64_t duration
Definition: ismindex.c:63
static int get_private_data(struct Track *track, AVCodecContext *codec)
Definition: ismindex.c:237
main external API structure.
uint8_t * codec_private
Definition: ismindex.c:70
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> (&#39;D&#39;<<24) + (&#39;C&#39;<<16) + (&#39;B&#39;<<8) + &#39;A&#39;).
int timescale
Definition: ismindex.c:73
void * buf
Definition: avisynth_c.h:594
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
struct Track ** tracks
Definition: ismindex.c:82
int index
Definition: gxfenc.c:89
synthesis window for stochastic i
int avio_open2(AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: aviobuf.c:804
#define snprintf
Definition: snprintf.h:34
static void clean_tracks(struct Tracks *tracks)
Definition: ismindex.c:524
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
#define type
int track_id
Definition: ismindex.c:65
track
Definition: brsc.py:18
int codec_private_size
Definition: ismindex.c:71
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf.
Definition: error.c:53
static int get_video_private_data(struct Track *track, AVCodecContext *codec)
Definition: ismindex.c:247
Main libavformat public API header.
int video_track
Definition: ismindex.c:83
int blocksize
Definition: ismindex.c:75
static int handle_file(struct Tracks *tracks, const char *file, int split)
Definition: ismindex.c:279
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
Read packets of a media file to get stream information.
const char * name
Definition: ismindex.c:62
int den
denominator
Definition: rational.h:45
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
#define MKBETAG(a, b, c, d)
Definition: common.h:283
int duration
Definition: ismindex.c:58
int len
int channels
number of audio channels
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:299
int64_t duration
Decoding: duration of the stream, in AV_TIME_BASE fractional seconds.
Definition: avformat.h:1009
static int read_tfra(struct Tracks *tracks, int start_index, AVIOContext *f)
Definition: ismindex.c:146
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
int nb_audio_tracks
Definition: ismindex.c:84
int main(int argc, char **argv)
Definition: ismindex.c:536
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:679
void av_register_all(void)
Initialize libavformat and register all the muxers, demuxers and protocols.
Definition: allformats.c:52
int64_t offset
Definition: ismindex.c:57
int nb_video_tracks
Definition: ismindex.c:84