static int gxf_write_umf_material_description(AVFormatContext *s) { GXFContext *gxf = s->priv_data; AVIOContext *pb = s->pb; int timecode_base = gxf->time_base.den == 60000 ? 60 : 50; // XXX drop frame uint32_t timecode = gxf->nb_fields / (timecode_base * 3600) % 24 << 24 | // hours gxf->nb_fields / (timecode_base * 60) % 60 << 16 | // minutes gxf->nb_fields / timecode_base % 60 << 8 | // seconds gxf->nb_fields % timecode_base; // fields avio_wl32(pb, gxf->flags); avio_wl32(pb, gxf->nb_fields); /* length of the longest track */ avio_wl32(pb, gxf->nb_fields); /* length of the shortest track */ avio_wl32(pb, 0); /* mark in */ avio_wl32(pb, gxf->nb_fields); /* mark out */ avio_wl32(pb, 0); /* timecode mark in */ avio_wl32(pb, timecode); /* timecode mark out */ avio_wl64(pb, s->timestamp); /* modification time */ avio_wl64(pb, s->timestamp); /* creation time */ avio_wl16(pb, 0); /* reserved */ avio_wl16(pb, 0); /* reserved */ avio_wl16(pb, gxf->audio_tracks); avio_wl16(pb, 1); /* timecode track count */ avio_wl16(pb, 0); /* reserved */ avio_wl16(pb, gxf->mpeg_tracks); return 48; }
static void write_odml_master(AVFormatContext *s, int stream_index) { AVIOContext *pb = s->pb; AVStream *st = s->streams[stream_index]; AVCodecContext *enc = st->codec; AVIStream *avist = st->priv_data; unsigned char tag[5]; int j; /* Starting to lay out AVI OpenDML master index. * We want to make it JUNK entry for now, since we'd * like to get away without making AVI an OpenDML one * for compatibility reasons. */ avist->indexes.indx_start = ff_start_tag(pb, "JUNK"); avio_wl16(pb, 4); /* wLongsPerEntry */ avio_w8(pb, 0); /* bIndexSubType (0 == frame index) */ avio_w8(pb, 0); /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */ avio_wl32(pb, 0); /* nEntriesInUse (will fill out later on) */ ffio_wfourcc(pb, avi_stream2fourcc(tag, stream_index, enc->codec_type)); /* dwChunkId */ avio_wl64(pb, 0); /* dwReserved[3] */ avio_wl32(pb, 0); /* Must be 0. */ for (j = 0; j < AVI_MASTER_INDEX_SIZE * 2; j++) avio_wl64(pb, 0); ff_end_tag(pb, avist->indexes.indx_start); }
static int w64_write_trailer(AVFormatContext *s) { AVIOContext *pb = s->pb; WAVMuxContext *wav = s->priv_data; int64_t file_size; if (pb->seekable) { end_guid(pb, wav->data); file_size = avio_tell(pb); avio_seek(pb, 16, SEEK_SET); avio_wl64(pb, file_size); if (s->streams[0]->codec->codec_tag != 0x01) { int64_t number_of_samples; number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration, s->streams[0]->codec->sample_rate * (int64_t)s->streams[0]->time_base.num, s->streams[0]->time_base.den); avio_seek(pb, wav->fact_pos + 24, SEEK_SET); avio_wl64(pb, number_of_samples); } avio_seek(pb, file_size, SEEK_SET); avio_flush(pb); } return 0; }
static int w64_write_header(AVFormatContext *s) { WAVMuxContext *wav = s->priv_data; AVIOContext *pb = s->pb; int64_t start; int ret; avio_write(pb, ff_w64_guid_riff, sizeof(ff_w64_guid_riff)); avio_wl64(pb, -1); avio_write(pb, ff_w64_guid_wave, sizeof(ff_w64_guid_wave)); start_guid(pb, ff_w64_guid_fmt, &start); if ((ret = ff_put_wav_header(pb, s->streams[0]->codec, 0)) < 0) { av_log(s, AV_LOG_ERROR, "%s codec not supported\n", s->streams[0]->codec->codec ? s->streams[0]->codec->codec->name : "NONE"); return ret; } end_guid(pb, start); if (s->streams[0]->codec->codec_tag != 0x01 /* hence for all other than PCM */ && s->pb->seekable) { start_guid(pb, ff_w64_guid_fact, &wav->fact_pos); avio_wl64(pb, 0); end_guid(pb, wav->fact_pos); } start_guid(pb, ff_w64_guid_data, &wav->data); return 0; }
static int avi_write_ix(AVFormatContext *s) { AVIOContext *pb = s->pb; AVIContext *avi = s->priv_data; char tag[5]; char ix_tag[] = "ix00"; int i, j; av_assert0(pb->seekable); if (avi->riff_id > AVI_MASTER_INDEX_SIZE) { av_log(s, AV_LOG_ERROR, "Invalid riff index %d > %d\n", avi->riff_id, AVI_MASTER_INDEX_SIZE); return AVERROR(EINVAL); } for (i=0;i<s->nb_streams;i++) { AVIStream *avist= s->streams[i]->priv_data; int64_t ix, pos; avi_stream2fourcc(tag, i, s->streams[i]->codec->codec_type); ix_tag[3] = '0' + i; /* Writing AVI OpenDML leaf index chunk */ ix = avio_tell(pb); ffio_wfourcc(pb, ix_tag); /* ix?? */ avio_wl32(pb, avist->indexes.entry * 8 + 24); /* chunk size */ avio_wl16(pb, 2); /* wLongsPerEntry */ avio_w8(pb, 0); /* bIndexSubType (0 == frame index) */ avio_w8(pb, 1); /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */ avio_wl32(pb, avist->indexes.entry); /* nEntriesInUse */ ffio_wfourcc(pb, tag); /* dwChunkId */ avio_wl64(pb, avi->movi_list);/* qwBaseOffset */ avio_wl32(pb, 0); /* dwReserved_3 (must be 0) */ for (j=0; j<avist->indexes.entry; j++) { AVIIentry* ie = avi_get_ientry(&avist->indexes, j); avio_wl32(pb, ie->pos + 8); avio_wl32(pb, ((uint32_t)ie->len & ~0x80000000) | (ie->flags & 0x10 ? 0 : 0x80000000)); } avio_flush(pb); pos = avio_tell(pb); /* Updating one entry in the AVI OpenDML master index */ avio_seek(pb, avist->indexes.indx_start - 8, SEEK_SET); ffio_wfourcc(pb, "indx"); /* enabling this entry */ avio_skip(pb, 8); avio_wl32(pb, avi->riff_id); /* nEntriesInUse */ avio_skip(pb, 16*avi->riff_id); avio_wl64(pb, ix); /* qwOffset */ avio_wl32(pb, pos - ix); /* dwSize */ avio_wl32(pb, avist->indexes.entry); /* dwDuration */ avio_seek(pb, pos, SEEK_SET); } return 0; }
static void write_DSATTRIB_TRANSPORT_PROPERTIES_init(AVFormatContext *s, int stream_index) { AVIOContext *pb = s->pb; write_chunk_header2(s, &ff_DSATTRIB_TRANSPORT_PROPERTIES, 0x80000000 | stream_index); avio_wl64(pb, stream_index); avio_wl64(pb, -1); avio_wl64(pb, 0); finish_chunk(s); }
static int gxf_write_umf_media_audio(AVIOContext *pb, GXFStreamContext *sc) { avio_wl64(pb, av_double2int(1)); /* sound level to begin to */ avio_wl64(pb, av_double2int(1)); /* sound level to begin to */ avio_wl32(pb, 0); /* number of fields over which to ramp up sound level */ avio_wl32(pb, 0); /* number of fields over which to ramp down sound level */ avio_wl32(pb, 0); /* reserved */ avio_wl32(pb, 0); /* reserved */ return 32; }
static int gxf_write_umf_material_description(AVFormatContext *s) { GXFContext *gxf = s->priv_data; AVIOContext *pb = s->pb; int timecode_base = gxf->time_base.den == 60000 ? 60 : 50; int64_t timestamp = 0; AVDictionaryEntry *t; uint64_t nb_fields; uint32_t timecode_in; // timecode at mark in uint32_t timecode_out; // timecode at mark out #if FF_API_TIMESTAMP if (s->timestamp) timestamp = s->timestamp; else #endif if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) timestamp = ff_iso8601_to_unix_time(t->value); timecode_in = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop, gxf->tc.hh, gxf->tc.mm, gxf->tc.ss, gxf->tc.ff); nb_fields = gxf->nb_fields + gxf->tc.hh * (timecode_base * 3600) + gxf->tc.mm * (timecode_base * 60) + gxf->tc.ss * timecode_base + gxf->tc.ff; timecode_out = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop, nb_fields / (timecode_base * 3600) % 24, nb_fields / (timecode_base * 60) % 60, nb_fields / timecode_base % 60, nb_fields % timecode_base); avio_wl32(pb, gxf->flags); avio_wl32(pb, gxf->nb_fields); /* length of the longest track */ avio_wl32(pb, gxf->nb_fields); /* length of the shortest track */ avio_wl32(pb, 0); /* mark in */ avio_wl32(pb, gxf->nb_fields); /* mark out */ avio_wl32(pb, timecode_in); /* timecode mark in */ avio_wl32(pb, timecode_out); /* timecode mark out */ avio_wl64(pb, timestamp); /* modification time */ avio_wl64(pb, timestamp); /* creation time */ avio_wl16(pb, 0); /* reserved */ avio_wl16(pb, 0); /* reserved */ avio_wl16(pb, gxf->audio_tracks); avio_wl16(pb, 1); /* timecode track count */ avio_wl16(pb, 0); /* reserved */ avio_wl16(pb, gxf->mpeg_tracks); return 48; }
static int ivf_write_header(AVFormatContext *s) { AVCodecParameters *par; AVIOContext *pb = s->pb; if (s->nb_streams != 1) { av_log(s, AV_LOG_ERROR, "Format supports only exactly one video stream\n"); return AVERROR(EINVAL); } par = s->streams[0]->codecpar; if (par->codec_type != AVMEDIA_TYPE_VIDEO || !(par->codec_id == AV_CODEC_ID_AV1 || par->codec_id == AV_CODEC_ID_VP8 || par->codec_id == AV_CODEC_ID_VP9)) { av_log(s, AV_LOG_ERROR, "Currently only AV1, VP8 and VP9 are supported!\n"); return AVERROR(EINVAL); } avio_write(pb, "DKIF", 4); avio_wl16(pb, 0); // version avio_wl16(pb, 32); // header length avio_wl32(pb, par->codec_tag ? par->codec_tag : ff_codec_get_tag(ff_codec_bmp_tags, par->codec_id)); avio_wl16(pb, par->width); avio_wl16(pb, par->height); avio_wl32(pb, s->streams[0]->time_base.den); avio_wl32(pb, s->streams[0]->time_base.num); avio_wl64(pb, s->streams[0]->duration); // TODO: duration or number of frames?!? return 0; }
static int write_table0_header_time(AVIOContext *pb) { avio_wl32(pb, 0x10); write_pad(pb, 76); avio_wl64(pb, 0x40); return 88; }
static int write_table0_header_events(AVIOContext *pb) { avio_wl32(pb, 0x10); write_pad(pb, 84); avio_wl64(pb, 0x32); return 96; }
static void write_sync(AVFormatContext *s) { AVIOContext *pb = s->pb; WtvContext *wctx = s->priv_data; int64_t last_chunk_pos = wctx->last_chunk_pos; write_chunk_header(s, &ff_sync_guid, 0x18, 0); avio_wl64(pb, wctx->first_index_pos); avio_wl64(pb, wctx->last_timestamp_pos); avio_wl64(pb, 0); finish_chunk(s); add_serial_pair(&wctx->sp_pairs, &wctx->nb_sp_pairs, wctx->serial, wctx->last_chunk_pos); wctx->last_chunk_pos = last_chunk_pos; }
static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc, int index) { GXFContext *gxf = s->priv_data; AVIOContext *pb = s->pb; int64_t pos; /* track description section */ avio_w8(pb, sc->media_type + 0x80); avio_w8(pb, index + 0xC0); pos = avio_tell(pb); avio_wb16(pb, 0); /* size */ /* media file name */ avio_w8(pb, TRACK_NAME); avio_w8(pb, strlen(ES_NAME_PATTERN) + 3); avio_write(pb, ES_NAME_PATTERN, sizeof(ES_NAME_PATTERN) - 1); avio_wb16(pb, sc->media_info); avio_w8(pb, 0); switch (sc->track_type) { case 3: /* timecode */ gxf_write_timecode_auxiliary(pb, gxf); break; case 4: /* MPEG2 */ case 9: /* MPEG1 */ gxf_write_mpeg_auxiliary(pb, s->streams[index]); break; case 5: /* DV25 */ case 6: /* DV50 */ gxf_write_dv_auxiliary(pb, s->streams[index]); break; default: avio_w8(pb, TRACK_AUX); avio_w8(pb, 8); avio_wl64(pb, 0); } /* file system version */ avio_w8(pb, TRACK_VER); avio_w8(pb, 4); avio_wb32(pb, 0); /* frame rate */ avio_w8(pb, TRACK_FPS); avio_w8(pb, 4); avio_wb32(pb, sc->frame_rate_index); /* lines per frame */ avio_w8(pb, TRACK_LINES); avio_w8(pb, 4); avio_wb32(pb, sc->lines_index); /* fields per frame */ avio_w8(pb, TRACK_FPF); avio_w8(pb, 4); avio_wb32(pb, sc->fields); return updateSize(pb, pos); }
static void update_odml_entry(AVFormatContext *s, int stream_index, int64_t ix, int size) { AVIOContext *pb = s->pb; AVIContext *avi = s->priv_data; AVIStream *avist = s->streams[stream_index]->priv_data; int64_t pos; int au_byterate, au_ssize, au_scale; avio_flush(pb); pos = avio_tell(pb); /* Updating one entry in the AVI OpenDML master index */ avio_seek(pb, avist->indexes.indx_start - 8, SEEK_SET); ffio_wfourcc(pb, "indx"); /* enabling this entry */ avio_skip(pb, 8); avio_wl32(pb, avi->riff_id - avist->indexes.master_odml_riff_id_base); /* nEntriesInUse */ avio_skip(pb, 16 * (avi->riff_id - avist->indexes.master_odml_riff_id_base)); avio_wl64(pb, ix); /* qwOffset */ avio_wl32(pb, size); /* dwSize */ ff_parse_specific_params(s->streams[stream_index], &au_byterate, &au_ssize, &au_scale); if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO && au_ssize > 0) { uint32_t audio_segm_size = (avist->audio_strm_length - avist->indexes.audio_strm_offset); if ((audio_segm_size % au_ssize > 0) && !avist->sample_requested) { avpriv_request_sample(s, "OpenDML index duration for audio packets with partial frames"); avist->sample_requested = 1; } avio_wl32(pb, audio_segm_size / au_ssize); /* dwDuration (sample count) */ } else avio_wl32(pb, avist->indexes.entry); /* dwDuration (packet count) */ avio_seek(pb, pos, SEEK_SET); }
static void start_guid(AVIOContext *pb, const uint8_t *guid, int64_t *pos) { *pos = avio_tell(pb); avio_write(pb, guid, 16); avio_wl64(pb, INT64_MAX); }
static int ivf_write_header(AVFormatContext *s) { AVCodecContext *ctx; AVIOContext *pb = s->pb; if (s->nb_streams != 1) { av_log(s, AV_LOG_ERROR, "Format supports only exactly one video stream\n"); return AVERROR(EINVAL); } ctx = s->streams[0]->codec; if (ctx->codec_type != AVMEDIA_TYPE_VIDEO || ctx->codec_id != AV_CODEC_ID_VP8) { av_log(s, AV_LOG_ERROR, "Currently only VP8 is supported!\n"); return AVERROR(EINVAL); } avio_write(pb, "DKIF", 4); avio_wl16(pb, 0); // version avio_wl16(pb, 32); // header length avio_wl32(pb, ctx->codec_tag ? ctx->codec_tag : AV_RL32("VP80")); avio_wl16(pb, ctx->width); avio_wl16(pb, ctx->height); avio_wl32(pb, s->streams[0]->time_base.den); avio_wl32(pb, s->streams[0]->time_base.num); avio_wl64(pb, s->streams[0]->duration); // TODO: duration or number of frames?!? return 0; }
static int ivf_write_header(AVFormatContext *s) { AVCodecParameters *par; AVIOContext *pb = s->pb; if (s->nb_streams != 1) { av_log(s, AV_LOG_ERROR, "Format supports only exactly one video stream\n"); return AVERROR(EINVAL); } par = s->streams[0]->codecpar; if (par->codec_type != AVMEDIA_TYPE_VIDEO || !(par->codec_id == AV_CODEC_ID_AV1 || par->codec_id == AV_CODEC_ID_VP8 || par->codec_id == AV_CODEC_ID_VP9)) { av_log(s, AV_LOG_ERROR, "Currently only VP8, VP9 and AV1 are supported!\n"); return AVERROR(EINVAL); } avio_write(pb, "DKIF", 4); avio_wl16(pb, 0); // version avio_wl16(pb, 32); // header length avio_wl32(pb, par->codec_tag ? par->codec_tag : par->codec_id == AV_CODEC_ID_VP9 ? AV_RL32("VP90") : par->codec_id == AV_CODEC_ID_VP8 ? AV_RL32("VP80") : AV_RL32("AV01")); avio_wl16(pb, par->width); avio_wl16(pb, par->height); avio_wl32(pb, s->streams[0]->time_base.den); avio_wl32(pb, s->streams[0]->time_base.num); avio_wl64(pb, 0xFFFFFFFFFFFFFFFFULL); return 0; }
static int write_root_table(AVFormatContext *s, int64_t sector_pos) { AVIOContext *pb = s->pb; WtvContext *wctx = s->priv_data; int size, pad; int i; const WTVRootEntryTable *h = wtv_root_entry_table; for (i = 0; i < sizeof(wtv_root_entry_table)/sizeof(WTVRootEntryTable); i++, h++) { WtvFile *w = &wctx->file[i]; int filename_padding = WTV_PAD8(h->header_size) - h->header_size; WTVHeaderWriteFunc *write = h->write_header; int len = 0; int64_t len_pos; ff_put_guid(pb, &ff_dir_entry_guid); len_pos = avio_tell(pb); avio_wl16(pb, 40 + h->header_size + filename_padding + 8); // maybe updated later write_pad(pb, 6); avio_wl64(pb, write ? 0 : w->length);// maybe update later avio_wl32(pb, (h->header_size + filename_padding) >> 1); write_pad(pb, 4); avio_write(pb, h->header, h->header_size); write_pad(pb, filename_padding); if (write) { len = write(pb); // update length field avio_seek(pb, len_pos, SEEK_SET); avio_wl64(pb, 40 + h->header_size + filename_padding + len); avio_wl64(pb, len |(1ULL<<62) | (1ULL<<60)); avio_seek(pb, 8 + h->header_size + filename_padding + len, SEEK_CUR); } else { avio_wl32(pb, w->first_sector); avio_wl32(pb, w->depth); } } // caculate root table size size = avio_tell(pb) - sector_pos; pad = WTV_SECTOR_SIZE- size; write_pad(pb, pad); return size; }
static int asf_write_index(AVFormatContext *s, ASFIndex *index, uint16_t max, uint32_t count) { AVIOContext *pb = s->pb; int i; ff_put_guid(pb, &ff_asf_simple_index_header); avio_wl64(pb, 24 + 16 + 8 + 4 + 4 + (4 + 2)*count); ff_put_guid(pb, &ff_asf_my_guid); avio_wl64(pb, ASF_INDEXED_INTERVAL); avio_wl32(pb, max); avio_wl32(pb, count); for(i=0; i<count; i++) { avio_wl32(pb, index[i].packet_number); avio_wl16(pb, index[i].packet_count); } return 0; }
/* update header size */ static void end_header(AVIOContext *pb, int64_t pos) { int64_t pos1; pos1 = avio_tell(pb); avio_seek(pb, pos + 16, SEEK_SET); avio_wl64(pb, pos1 - pos); avio_seek(pb, pos1, SEEK_SET); }
static void write_chunk_header2(AVFormatContext *s, const ff_asf_guid *guid, int stream_id) { WtvContext *wctx = s->priv_data; AVIOContext *pb = s->pb; int64_t last_chunk_pos = wctx->last_chunk_pos; write_chunk_header(s, guid, 0, stream_id); // length updated later avio_wl64(pb, last_chunk_pos); }
static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; avio_wl32(pb, pkt->size); avio_wl64(pb, pkt->pts); avio_write(pb, pkt->data, pkt->size); return 0; }
static int64_t put_header(AVIOContext *pb, const ff_asf_guid *g) { int64_t pos; pos = avio_tell(pb); ff_put_guid(pb, g); avio_wl64(pb, 24); return pos; }
static int avi_write_ix(AVFormatContext *s) { AVIOContext *pb = s->pb; AVIContext *avi = s->priv_data; char tag[5]; char ix_tag[] = "ix00"; int i, j; av_assert0(pb->seekable); for (i = 0; i < s->nb_streams; i++) { AVIStream *avist = s->streams[i]->priv_data; if (avi->riff_id - avist->indexes.master_odml_riff_id_base == AVI_MASTER_INDEX_SIZE) { int64_t pos; int size = 8+2+1+1+4+8+4+4+16*AVI_MASTER_INDEX_SIZE; pos = avio_tell(pb); update_odml_entry(s, i, pos, size); write_odml_master(s, i); av_assert1(avio_tell(pb) - pos == size); avist->indexes.master_odml_riff_id_base = avi->riff_id - 1; } av_assert0(avi->riff_id - avist->indexes.master_odml_riff_id_base < AVI_MASTER_INDEX_SIZE); } for (i = 0; i < s->nb_streams; i++) { AVIStream *avist = s->streams[i]->priv_data; int64_t ix; avi_stream2fourcc(tag, i, s->streams[i]->codec->codec_type); ix_tag[3] = '0' + i; /* Writing AVI OpenDML leaf index chunk */ ix = avio_tell(pb); ffio_wfourcc(pb, ix_tag); /* ix?? */ avio_wl32(pb, avist->indexes.entry * 8 + 24); /* chunk size */ avio_wl16(pb, 2); /* wLongsPerEntry */ avio_w8(pb, 0); /* bIndexSubType (0 == frame index) */ avio_w8(pb, 1); /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */ avio_wl32(pb, avist->indexes.entry); /* nEntriesInUse */ ffio_wfourcc(pb, tag); /* dwChunkId */ avio_wl64(pb, avi->movi_list); /* qwBaseOffset */ avio_wl32(pb, 0); /* dwReserved_3 (must be 0) */ for (j = 0; j < avist->indexes.entry; j++) { AVIIentry *ie = avi_get_ientry(&avist->indexes, j); avio_wl32(pb, ie->pos + 8); avio_wl32(pb, ((uint32_t) ie->len & ~0x80000000) | (ie->flags & 0x10 ? 0 : 0x80000000)); } update_odml_entry(s, i, ix, avio_tell(pb) - ix); } return 0; }
static int sox_write_header(AVFormatContext *s) { SoXContext *sox = s->priv_data; AVIOContext *pb = s->pb; AVCodecContext *enc = s->streams[0]->codec; AVDictionaryEntry *comment; size_t comment_len = 0, comment_size; comment = av_dict_get(s->metadata, "comment", NULL, 0); if (comment) comment_len = strlen(comment->value); comment_size = (comment_len + 7) & ~7; sox->header_size = SOX_FIXED_HDR + comment_size; if (enc->codec_id == AV_CODEC_ID_PCM_S32LE) { ffio_wfourcc(pb, ".SoX"); avio_wl32(pb, sox->header_size); avio_wl64(pb, 0); /* number of samples */ avio_wl64(pb, av_double2int(enc->sample_rate)); avio_wl32(pb, enc->channels); avio_wl32(pb, comment_size); } else if (enc->codec_id == AV_CODEC_ID_PCM_S32BE) { ffio_wfourcc(pb, "XoS."); avio_wb32(pb, sox->header_size); avio_wb64(pb, 0); /* number of samples */ avio_wb64(pb, av_double2int(enc->sample_rate)); avio_wb32(pb, enc->channels); avio_wb32(pb, comment_size); } else { av_log(s, AV_LOG_ERROR, "invalid codec; use pcm_s32le or pcm_s32be\n"); return -1; } if (comment_len) avio_write(pb, comment->value, comment_len); for ( ; comment_size > comment_len; comment_len++) avio_w8(pb, 0); avio_flush(pb); return 0; }
static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc, int index) { GXFContext *gxf = s->priv_data; AVIOContext *pb = s->pb; int64_t pos; int mpeg = sc->track_type == 4 || sc->track_type == 9; /* track description section */ avio_w8(pb, sc->media_type + 0x80); avio_w8(pb, index + 0xC0); pos = avio_tell(pb); avio_wb16(pb, 0); /* size */ /* media file name */ avio_w8(pb, TRACK_NAME); avio_w8(pb, strlen(ES_NAME_PATTERN) + 3); avio_write(pb, ES_NAME_PATTERN, sizeof(ES_NAME_PATTERN) - 1); avio_wb16(pb, sc->media_info); avio_w8(pb, 0); if (!mpeg) { /* auxiliary information */ avio_w8(pb, TRACK_AUX); avio_w8(pb, 8); if (sc->track_type == 3) gxf_write_timecode_auxiliary(pb, gxf); else avio_wl64(pb, 0); } /* file system version */ avio_w8(pb, TRACK_VER); avio_w8(pb, 4); avio_wb32(pb, 0); if (mpeg) gxf_write_mpeg_auxiliary(pb, s->streams[index]); /* frame rate */ avio_w8(pb, TRACK_FPS); avio_w8(pb, 4); avio_wb32(pb, sc->frame_rate_index); /* lines per frame */ avio_w8(pb, TRACK_LINES); avio_w8(pb, 4); avio_wb32(pb, sc->lines_index); /* fields per frame */ avio_w8(pb, TRACK_FPF); avio_w8(pb, 4); avio_wb32(pb, sc->fields); return updateSize(pb, pos); }
static void end_guid(AVIOContext *pb, int64_t start) { int64_t end, pos = avio_tell(pb); end = FFALIGN(pos, 8); ffio_fill(pb, 0, end - pos); avio_seek(pb, start + 16, SEEK_SET); avio_wl64(pb, end - start); avio_seek(pb, end, SEEK_SET); }
static int asf_write_markers(AVFormatContext *s) { ASFContext *asf = s->priv_data; AVIOContext *pb = s->pb; int i; AVRational scale = {1, 10000000}; int64_t hpos = put_header(pb, &ff_asf_marker_header); ff_put_guid(pb, &ff_asf_reserved_4);// ASF spec mandates this reserved value avio_wl32(pb, s->nb_chapters); // markers count avio_wl16(pb, 0); // ASF spec mandates 0 for this avio_wl16(pb, 0); // name length 0, no name given for (i = 0; i < s->nb_chapters; i++) { AVChapter *c = s->chapters[i]; AVDictionaryEntry *t = av_dict_get(c->metadata, "title", NULL, 0); int64_t pres_time = av_rescale_q(c->start, c->time_base, scale); uint64_t offset; int32_t send_time = get_send_time(asf, pres_time, &offset); int len = 0; uint8_t *buf; AVIOContext *dyn_buf; if (t) { if (avio_open_dyn_buf(&dyn_buf) < 0) return AVERROR(ENOMEM); avio_put_str16le(dyn_buf, t->value); len = avio_close_dyn_buf(dyn_buf, &buf); } avio_wl64(pb, offset); // offset of the packet with send_time avio_wl64(pb, pres_time + PREROLL_TIME * 10000); // presentation time avio_wl16(pb, 12 + len); // entry length avio_wl32(pb, send_time); // send time avio_wl32(pb, 0); // flags, should be 0 avio_wl32(pb, len / 2); // marker desc length in WCHARS! if (t) { avio_write(pb, buf, len); // marker desc av_freep(&buf); } } end_header(pb, hpos); return 0; }
static int gxf_write_umf_material_description(AVFormatContext *s) { GXFContext *gxf = s->priv_data; AVIOContext *pb = s->pb; int timecode_base = gxf->time_base.den == 60000 ? 60 : 50; int64_t timestamp = 0; AVDictionaryEntry *t; uint32_t timecode; #if FF_API_TIMESTAMP if (s->timestamp) timestamp = s->timestamp; else #endif if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) timestamp = ff_iso8601_to_unix_time(t->value); // XXX drop frame timecode = gxf->nb_fields / (timecode_base * 3600) % 24 << 24 | // hours gxf->nb_fields / (timecode_base * 60) % 60 << 16 | // minutes gxf->nb_fields / timecode_base % 60 << 8 | // seconds gxf->nb_fields % timecode_base; // fields avio_wl32(pb, gxf->flags); avio_wl32(pb, gxf->nb_fields); /* length of the longest track */ avio_wl32(pb, gxf->nb_fields); /* length of the shortest track */ avio_wl32(pb, 0); /* mark in */ avio_wl32(pb, gxf->nb_fields); /* mark out */ avio_wl32(pb, 0); /* timecode mark in */ avio_wl32(pb, timecode); /* timecode mark out */ avio_wl64(pb, timestamp); /* modification time */ avio_wl64(pb, timestamp); /* creation time */ avio_wl16(pb, 0); /* reserved */ avio_wl16(pb, 0); /* reserved */ avio_wl16(pb, gxf->audio_tracks); avio_wl16(pb, 1); /* timecode track count */ avio_wl16(pb, 0); /* reserved */ avio_wl16(pb, gxf->mpeg_tracks); return 48; }
static int gxf_write_dv_auxiliary(AVIOContext *pb, AVStream *st) { int64_t track_aux_data = 0; avio_w8(pb, TRACK_AUX); avio_w8(pb, 8); if (st->codec->pix_fmt == AV_PIX_FMT_YUV420P) track_aux_data |= 0x01; /* marks stream as DVCAM instead of DVPRO */ track_aux_data |= 0x40000000; /* aux data is valid */ avio_wl64(pb, track_aux_data); return 8; }