58 static int usage(
const char *argv0, 
int ret)
 
   60     fprintf(stderr, 
"%s [-split] [-ismf] [-n basename] [-path-prefix prefix] " 
   61                     "[-ismc-prefix prefix] [-output dir] file1 [file2] ...\n", argv0);
 
   98     if (got_tag != expected_tag) {
 
   99         char got_tag_str[4], expected_tag_str[4];
 
  101         AV_WB32(expected_tag_str, expected_tag);
 
  102         fprintf(stderr, 
"wanted tag %.4s, got %.4s\n", expected_tag_str,
 
  124         if ((got = 
avio_read(in, buf, len)) != len) {
 
  125             fprintf(stderr, 
"short read, wanted %d, got %d\n", len, got);
 
  155         fprintf(stderr, 
"Unable to open %s: %s\n", filename, errbuf);
 
  179                            int split, 
int ismf, 
const char* output_prefix)
 
  181     char dirname[2048], filename[2048], idxname[2048];
 
  182     int i, j, ret = 0, fragment_ret;
 
  186         snprintf(idxname, 
sizeof(idxname), 
"%s%s.ismf", output_prefix, basename);
 
  187         out = fopen(idxname, 
"w");
 
  194     for (i = start_index; i < tracks->
nb_tracks; i++) {
 
  197         snprintf(dirname, 
sizeof(dirname), 
"%sQualityLevels(%d)", output_prefix, track->
bitrate);
 
  199             if (mkdir(dirname, 0777) == -1 && errno != EEXIST) {
 
  205         for (j = 0; j < track->
chunks; j++) {
 
  206             snprintf(filename, 
sizeof(filename), 
"%s/Fragments(%s=%"PRId64
")",
 
  210                 fprintf(out, 
"%s %"PRId64, filename, 
avio_tell(in));
 
  216                 fprintf(out, 
" %"PRId64
"\n", 
avio_tell(in));
 
  217             if (fragment_ret != 0) {
 
  218                 fprintf(stderr, 
"failed fragment %d in track %d (%s)\n", j,
 
  237     int64_t first_pts = 0;
 
  242         fprintf(stderr, 
"No sample duration in trun flags\n");
 
  251     for (i = 0; i < entries && pos < 
end; i++) {
 
  252         int sample_duration = default_duration;
 
  254         if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = 
avio_rb32(in);
 
  258         if (sample_duration < 0) {
 
  259             fprintf(stderr, 
"Negative sample duration %d\n", sample_duration);
 
  264         max_pts = 
FFMAX(max_pts, pts + sample_duration);
 
  265         dts += sample_duration;
 
  269     return max_pts - first_pts;
 
  277     int default_duration = 0;
 
  284     while (pos < offset + moof_size) {
 
  288         if (tag == 
MKBETAG(
't', 
'r', 
'a', 
'f')) {
 
  289             int64_t traf_pos = pos;
 
  290             int64_t traf_size = 
size;
 
  291             while (pos < traf_pos + traf_size) {
 
  295                 if (tag == 
MKBETAG(
't', 
'f', 
'h', 
'd')) {
 
  307                 if (tag == 
MKBETAG(
't', 
'r', 
'u', 
'n')) {
 
  313             fprintf(stderr, 
"Couldn't find trun\n");
 
  318     fprintf(stderr, 
"Couldn't find traf\n");
 
  327     int version, fieldlength, i, j;
 
  337     for (i = start_index; i < tracks->
nb_tracks && !track; i++)
 
  339             track = tracks->
tracks[i];
 
  355     for (i = 0; i < track->
chunks; i++) {
 
  363         for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
 
  365         for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
 
  367         for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
 
  379     for (i = 0; i < track->
chunks; i++) {
 
  381         if (duration > 0 && llabs(duration - track->
offsets[i].
duration) > 3) {
 
  389             fprintf(stderr, 
"Calculated last chunk duration for track %d " 
  390                     "was non-positive (%"PRId64
"), probably due to missing " 
  399             fprintf(stderr, 
"corrected to %"PRId64
"\n",
 
  404             fprintf(stderr, 
"Track duration corrected to %"PRId64
"\n",
 
  416                      const char *file, 
int split, 
int ismf,
 
  417                      const char *basename, 
const char* output_prefix)
 
  420     const char* err_str = 
"";
 
  431         err_str = 
"mfra size mismatch";
 
  436         err_str = 
"mfra tag mismatch";
 
  439     while (!
read_tfra(tracks, start_index, f)) {
 
  446     err_str = 
"error in write_fragments";
 
  452         fprintf(stderr, 
"Unable to read the MFRA atom in %s (%s)\n", file, err_str);
 
  470     uint16_t sps_size, pps_size;
 
  499                        int ismf, 
const char *basename,
 
  500                        const char* output_prefix)
 
  503     int err = 0, i, orig_tracks = tracks->
nb_tracks;
 
  504     char errbuf[50], *ptr;
 
  510         fprintf(stderr, 
"Unable to open %s: %s\n", file, errbuf);
 
  517         fprintf(stderr, 
"Unable to identify %s: %s\n", file, errbuf);
 
  522         fprintf(stderr, 
"No streams found in %s\n", file);
 
  531             fprintf(stderr, 
"Skipping track %d in %s as it has zero bitrate\n",
 
  553         if ((ptr = strrchr(file, 
'/')))
 
  554             track->
name = ptr + 1;
 
  565                     "Track %d in %s is neither video nor audio, skipping\n",
 
  610     err = 
read_mfra(tracks, orig_tracks, file, split, ismf, basename,
 
  620                                    const char *output_prefix,
 
  621                                    const char *path_prefix,
 
  622                                    const char *ismc_prefix)
 
  628     snprintf(filename, 
sizeof(filename), 
"%s%s.ism", output_prefix, basename);
 
  629     out = fopen(filename, 
"w");
 
  634     fprintf(out, 
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
 
  635     fprintf(out, 
"<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
 
  636     fprintf(out, 
"\t<head>\n");
 
  637     fprintf(out, 
"\t\t<meta name=\"clientManifestRelativePath\" " 
  638                  "content=\"%s%s.ismc\" />\n", ismc_prefix, basename);
 
  639     fprintf(out, 
"\t</head>\n");
 
  640     fprintf(out, 
"\t<body>\n");
 
  641     fprintf(out, 
"\t\t<switch>\n");
 
  642     for (i = 0; i < tracks->
nb_tracks; i++) {
 
  645         fprintf(out, 
"\t\t\t<%s src=\"%s%s\" systemBitrate=\"%d\">\n",
 
  647         fprintf(out, 
"\t\t\t\t<param name=\"trackID\" value=\"%d\" " 
  648                      "valueType=\"data\" />\n", track->
track_id);
 
  649         fprintf(out, 
"\t\t\t</%s>\n", type);
 
  651     fprintf(out, 
"\t\t</switch>\n");
 
  652     fprintf(out, 
"\t</body>\n");
 
  653     fprintf(out, 
"</smil>\n");
 
  663     int should_print_time_mismatch = 1;
 
  665     for (i = 0; i < track->
chunks; i++) {
 
  666         for (j = main + 1; j < tracks->
nb_tracks; j++) {
 
  669                     fprintf(stderr, 
"Mismatched duration of %s chunk %d in %s (%d) and %s (%d)\n",
 
  671                     should_print_time_mismatch = 1;
 
  674                     if (should_print_time_mismatch)
 
  675                         fprintf(stderr, 
"Mismatched (start) time of %s chunk %d in %s (%d) and %s (%d)\n",
 
  677                     should_print_time_mismatch = 0;
 
  681         fprintf(out, 
"\t\t<c n=\"%d\" d=\"%"PRId64
"\" ",
 
  684             fprintf(out, 
"t=\"%"PRId64
"\" ", track->
offsets[i].
time);
 
  688         fprintf(out, 
"/>\n");
 
  693                                    const char *output_prefix, 
int split)
 
  700         snprintf(filename, 
sizeof(filename), 
"%sManifest", output_prefix);
 
  702         snprintf(filename, 
sizeof(filename), 
"%s%s.ismc", output_prefix, basename);
 
  703     out = fopen(filename, 
"w");
 
  708     fprintf(out, 
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
 
  709     fprintf(out, 
"<SmoothStreamingMedia MajorVersion=\"2\" MinorVersion=\"0\" " 
  710                  "Duration=\"%"PRId64 
"\">\n", tracks->
duration * 10);
 
  713         struct Track *first_track = track;
 
  716                 "\t<StreamIndex Type=\"video\" QualityLevels=\"%d\" " 
  718                 "Url=\"QualityLevels({bitrate})/Fragments(video={start time})\">\n",
 
  720         for (i = 0; i < tracks->
nb_tracks; i++) {
 
  721             track = tracks->
tracks[i];
 
  725                     "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" " 
  726                     "FourCC=\"%s\" MaxWidth=\"%d\" MaxHeight=\"%d\" " 
  727                     "CodecPrivateData=\"",
 
  731             fprintf(out, 
"\" />\n");
 
  734                 fprintf(stderr, 
"Mismatched number of video chunks in %s (id: %d, chunks %d) and %s (id: %d, chunks %d)\n",
 
  738         fprintf(out, 
"\t</StreamIndex>\n");
 
  742         struct Track *first_track = track;
 
  745                 "\t<StreamIndex Type=\"audio\" QualityLevels=\"%d\" " 
  747                 "Url=\"QualityLevels({bitrate})/Fragments(audio={start time})\">\n",
 
  749         for (i = 0; i < tracks->
nb_tracks; i++) {
 
  750             track = tracks->
tracks[i];
 
  754                     "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" " 
  755                     "FourCC=\"%s\" SamplingRate=\"%d\" Channels=\"%d\" " 
  756                     "BitsPerSample=\"16\" PacketSize=\"%d\" " 
  757                     "AudioTag=\"%d\" CodecPrivateData=\"",
 
  762             fprintf(out, 
"\" />\n");
 
  765                 fprintf(stderr, 
"Mismatched number of audio chunks in %s and %s\n",
 
  769         fprintf(out, 
"\t</StreamIndex>\n");
 
  771     fprintf(out, 
"</SmoothStreamingMedia>\n");
 
  778     for (i = 0; i < tracks->
nb_tracks; i++) {
 
  787 int main(
int argc, 
char **argv)
 
  789     const char *basename = 
NULL;
 
  790     const char *path_prefix = 
"", *ismc_prefix = 
"";
 
  791     const char *output_prefix = 
"";
 
  792     char output_prefix_buf[2048];
 
  793     int split = 0, ismf = 0, i;
 
  798     for (i = 1; i < argc; i++) {
 
  799         if (!strcmp(argv[i], 
"-n")) {
 
  800             basename = argv[i + 1];
 
  802         } 
else if (!strcmp(argv[i], 
"-path-prefix")) {
 
  803             path_prefix = argv[i + 1];
 
  805         } 
else if (!strcmp(argv[i], 
"-ismc-prefix")) {
 
  806             ismc_prefix = argv[i + 1];
 
  808         } 
else if (!strcmp(argv[i], 
"-output")) {
 
  809             output_prefix = argv[i + 1];
 
  811             if (output_prefix[strlen(output_prefix) - 1] != 
'/') {
 
  812                 snprintf(output_prefix_buf, 
sizeof(output_prefix_buf),
 
  813                          "%s/", output_prefix);
 
  814                 output_prefix = output_prefix_buf;
 
  816         } 
else if (!strcmp(argv[i], 
"-split")) {
 
  818         } 
else if (!strcmp(argv[i], 
"-ismf")) {
 
  820         } 
else if (argv[i][0] == 
'-') {
 
  821             return usage(argv[0], 1);
 
  826                             basename, output_prefix))
 
  830     if (!tracks.
nb_tracks || (!basename && !split))
 
  831         return usage(argv[0], 1);
 
  835                                path_prefix, ismc_prefix);
 
static int copy_tag(AVIOContext *in, AVIOContext *out, int32_t tag_name)
#define AVERROR_INVALIDDATA
Invalid data found when processing input. 
int64_t avio_size(AVIOContext *s)
Get the filesize. 
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer. 
static int usage(const char *argv0, int ret)
#define MOV_TFHD_DEFAULT_DURATION
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. 
int64_t bit_rate
the average bitrate 
#define MOV_TRUN_SAMPLE_CTS
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext. 
#define AVIO_FLAG_READ
read-only 
#define AVIO_FLAG_WRITE
write-only 
static int expect_tag(int32_t got_tag, int32_t expected_tag)
static void print_track_chunks(FILE *out, struct Tracks *tracks, int main, const char *type)
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_WB24 unsigned int_TMPL AV_RB16
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream. 
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs...
struct MoofOffset * offsets
miscellaneous OS support macros and functions. 
unsigned int avio_rb32(AVIOContext *s)
static av_cold int end(AVCodecContext *avctx)
int id
Format-specific stream ID. 
uint8_t * extradata
some codecs need / can use extradata like Huffman tables. 
AVStream ** streams
A list of all streams in the file. 
static int skip_fragment(AVIOContext *in)
#define MOV_TRUN_SAMPLE_SIZE
#define AVERROR_EOF
End of file. 
uint64_t avio_rb64(AVIOContext *s)
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext. 
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
static int write_fragment(const char *filename, AVIOContext *in)
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf. 
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it. 
static void output_client_manifest(struct Tracks *tracks, const char *basename, const char *output_prefix, int split)
static int read_mfra(struct Tracks *tracks, int start_index, const char *file, int split, int ismf, const char *basename, const char *output_prefix)
static const uint8_t offset[127][2]
static char * split(char *message, char delim)
int avio_r8(AVIOContext *s)
AVCodecContext * codec
Codec context associated with this stream. 
unsigned int nb_streams
Number of elements in AVFormatContext.streams. 
int void avio_flush(AVIOContext *s)
Force flushing of buffered data. 
unsigned int avio_rb24(AVIOContext *s)
#define AV_TIME_BASE
Internal time base represented as integer. 
static int handle_file(struct Tracks *tracks, const char *file, int split, int ismf, const char *basename, const char *output_prefix)
int width
picture width / height. 
#define MOV_TRUN_SAMPLE_DURATION
static int64_t read_moof_duration(AVIOContext *in, int64_t offset)
enum AVMediaType codec_type
static int skip_tag(AVIOContext *in, int32_t tag_name)
int sample_rate
samples per second 
static int get_private_data(struct Track *track, AVCodecContext *codec)
main external API structure. 
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). 
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;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);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
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. 
static void clean_tracks(struct Tracks *tracks)
#define MOV_TRUN_SAMPLE_FLAGS
static int64_t pts
Global timestamp for the audio frames. 
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf. 
int64_t duration
Decoding: duration of the stream, in stream time base. 
static int get_video_private_data(struct Track *track, AVCodecContext *codec)
#define MOV_TFHD_BASE_DATA_OFFSET
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
Read packets of a media file to get stream information. 
static int write_fragments(struct Tracks *tracks, int start_index, AVIOContext *in, const char *basename, int split, int ismf, const char *output_prefix)
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext. 
#define MKBETAG(a, b, c, d)
int channels
number of audio channels 
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header. 
#define MOV_TRUN_DATA_OFFSET
static void * av_mallocz_array(size_t nmemb, size_t size)
void avio_wb32(AVIOContext *s, unsigned int val)
static int read_tfra(struct Tracks *tracks, int start_index, AVIOContext *f)
int main(int argc, char **argv)
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
void av_register_all(void)
Initialize libavformat and register all the muxers, demuxers and protocols. 
static void output_server_manifest(struct Tracks *tracks, const char *basename, const char *output_prefix, const char *path_prefix, const char *ismc_prefix)
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
static int64_t read_trun_duration(AVIOContext *in, int default_duration, int64_t end)