📄 movenc.c
字号:
put_byte(pb, vals[3]); } else if (size < 0x10000000) { put_byte(pb, vals[0]); put_byte(pb, vals[1]); put_byte(pb, vals[2]); put_byte(pb, vals[3]); }}static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic{ int decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0; int pos = url_ftell(pb); put_be32(pb, 0); // size put_tag(pb, "esds"); put_be32(pb, 0); // Version // ES descriptor putDescr(pb, 0x03, 3 + descrLength(13 + decoderSpecificInfoLen) + descrLength(1)); put_be16(pb, 0x0001); // ID (= 1) put_byte(pb, 0x00); // flags (= no flags) // DecoderConfig descriptor putDescr(pb, 0x04, 13 + decoderSpecificInfoLen); if(track->enc->codec_id == CODEC_ID_AAC) put_byte(pb, 0x40); // Object type indication else if(track->enc->codec_id == CODEC_ID_MPEG4) put_byte(pb, 0x20); // Object type indication (Visual 14496-2) if(track->enc->codec_type == CODEC_TYPE_AUDIO) put_byte(pb, 0x15); // flags (= Audiostream) else put_byte(pb, 0x11); // flags (= Visualstream) put_byte(pb, 0x0); // Buffersize DB (24 bits) put_be16(pb, 0x0dd2); // Buffersize DB // TODO: find real values for these put_be32(pb, 0x0002e918); // maxbitrate put_be32(pb, 0x00017e6b); // avg bitrate if (track->vosLen) { // DecoderSpecific info descriptor putDescr(pb, 0x05, track->vosLen); put_buffer(pb, track->vosData, track->vosLen); } // SL descriptor putDescr(pb, 0x06, 1); put_byte(pb, 0x02); return updateSize (pb, pos);}const CodecTag codec_movvideo_tags[] = { { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, { CODEC_ID_H263, MKTAG('s', '2', '6', '3') }, { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, { 0, 0 },};static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track){ int pos = url_ftell(pb), tag; put_be32(pb, 0); /* size */ tag = codec_get_tag(codec_movvideo_tags, track->enc->codec_id); // if no mac fcc found, try with Microsoft tags if (!tag) tag = codec_get_tag(codec_bmp_tags, track->enc->codec_id); if (!tag) put_tag(pb, " "); else put_le32(pb, tag); // store it byteswapped put_be32(pb, 0); /* Reserved */ put_be16(pb, 0); /* Reserved */ put_be16(pb, 1); /* Data-reference index */ put_be32(pb, 0); /* Reserved (= 02000c) */ put_be32(pb, 0); /* Reserved ("SVis")*/ put_be32(pb, 0); /* Reserved */ put_be32(pb, 0); /* Reserved (400)*/ put_be16(pb, track->enc->width); /* Video width */ put_be16(pb, track->enc->height); /* Video height */ put_be32(pb, 0x00480000); /* Reserved */ put_be32(pb, 0x00480000); /* Reserved */ put_be32(pb, 0); /* Data size (= 0) */ put_be16(pb, 1); /* Frame count (= 1) */ put_be32(pb, 0); /* Reserved */ put_be32(pb, 0); /* Reserved */ put_be32(pb, 0); /* Reserved */ put_be32(pb, 0); /* Reserved */ put_be32(pb, 0); /* Reserved */ put_be32(pb, 0); /* Reserved */ put_be32(pb, 0); /* Reserved */ put_be32(pb, 0); /* Reserved */ put_be16(pb, 0x18); /* Reserved */ put_be16(pb, 0xffff); /* Reserved */ if(track->enc->codec_id == CODEC_ID_MPEG4) mov_write_esds_tag(pb, track); else if(track->enc->codec_id == CODEC_ID_H263) mov_write_d263_tag(pb); else if(track->enc->codec_id == CODEC_ID_SVQ3) mov_write_svq3_tag(pb); return updateSize (pb, pos);}static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack* track){ int pos = url_ftell(pb); put_be32(pb, 0); /* size */ put_tag(pb, "stsd"); put_be32(pb, 0); /* version & flags */ put_be32(pb, 1); /* entry count */ if (track->enc->codec_type == CODEC_TYPE_VIDEO) mov_write_video_tag(pb, track); else if (track->enc->codec_type == CODEC_TYPE_AUDIO) mov_write_audio_tag(pb, track); return updateSize(pb, pos);}/* TODO?: Currently all samples/frames seem to have same duration *//* Time to sample atom */static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track){ put_be32(pb, 0x18); /* size */ put_tag(pb, "stts"); put_be32(pb, 0); /* version & flags */ put_be32(pb, 1); /* entry count */ put_be32(pb, track->sampleCount); /* sample count */ put_be32(pb, track->sampleDuration); /* sample duration */ return 0x18;}static int mov_write_dref_tag(ByteIOContext *pb){ put_be32(pb, 28); /* size */ put_tag(pb, "dref"); put_be32(pb, 0); /* version & flags */ put_be32(pb, 1); /* entry count */ put_be32(pb, 0xc); /* size */ put_tag(pb, "url "); put_be32(pb, 1); /* version & flags */ return 28;}static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack* track){ int pos = url_ftell(pb); put_be32(pb, 0); /* size */ put_tag(pb, "stbl"); mov_write_stsd_tag(pb, track); mov_write_stts_tag(pb, track); if (track->enc->codec_type == CODEC_TYPE_VIDEO && track->hasKeyframes) mov_write_stss_tag(pb, track); mov_write_stsc_tag(pb, track); mov_write_stsz_tag(pb, track); mov_write_stco_tag(pb, track); return updateSize(pb, pos);}static int mov_write_dinf_tag(ByteIOContext *pb){ int pos = url_ftell(pb); put_be32(pb, 0); /* size */ put_tag(pb, "dinf"); mov_write_dref_tag(pb); return updateSize(pb, pos);}static int mov_write_smhd_tag(ByteIOContext *pb){ put_be32(pb, 16); /* size */ put_tag(pb, "smhd"); put_be32(pb, 0); /* version & flags */ put_be16(pb, 0); /* reserved (balance, normally = 0) */ put_be16(pb, 0); /* reserved */ return 16;}static int mov_write_vmhd_tag(ByteIOContext *pb){ put_be32(pb, 0x14); /* size (always 0x14) */ put_tag(pb, "vmhd"); put_be32(pb, 0x01); /* version & flags */ put_be64(pb, 0); /* reserved (graphics mode = copy) */ return 0x14;}static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack* track){ char *descr, *hdlr, *hdlr_type; int pos = url_ftell(pb); if (!track) { /* no media --> data handler */ hdlr = "dhlr"; hdlr_type = "url "; descr = "DataHandler"; } else { hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0"; if (track->enc->codec_type == CODEC_TYPE_VIDEO) { hdlr_type = "vide"; descr = "VideoHandler"; } else { hdlr_type = "soun"; descr = "SoundHandler"; } } put_be32(pb, 0); /* size */ put_tag(pb, "hdlr"); put_be32(pb, 0); /* Version & flags */ put_buffer(pb, hdlr, 4); /* handler */ put_tag(pb, hdlr_type); /* handler type */ put_be32(pb ,0); /* reserved */ put_be32(pb ,0); /* reserved */ put_be32(pb ,0); /* reserved */ put_byte(pb, strlen(descr)); /* string counter */ put_buffer(pb, descr, strlen(descr)); /* handler description */ return updateSize(pb, pos);}static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack* track){ int pos = url_ftell(pb); put_be32(pb, 0); /* size */ put_tag(pb, "minf"); if(track->enc->codec_type == CODEC_TYPE_VIDEO) mov_write_vmhd_tag(pb); else mov_write_smhd_tag(pb); if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */ mov_write_hdlr_tag(pb, NULL); mov_write_dinf_tag(pb); mov_write_stbl_tag(pb, track); return updateSize(pb, pos);}static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack* track){ put_be32(pb, 32); /* size */ put_tag(pb, "mdhd"); put_be32(pb, 0); /* Version & flags */ put_be32(pb, track->time); /* creation time */ put_be32(pb, track->time); /* modification time */ put_be32(pb, track->timescale); /* time scale (sample rate for audio) */ put_be32(pb, track->trackDuration); /* duration */ put_be16(pb, 0); /* language, 0 = english */ put_be16(pb, 0); /* reserved (quality) */ return 32;}static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack* track){ int pos = url_ftell(pb); put_be32(pb, 0); /* size */ put_tag(pb, "mdia"); mov_write_mdhd_tag(pb, track); mov_write_hdlr_tag(pb, track); mov_write_minf_tag(pb, track); return updateSize(pb, pos);}static int mov_write_tkhd_tag(ByteIOContext *pb, MOVTrack* track){ int64_t maxTrackLenTemp; put_be32(pb, 0x5c); /* size (always 0x5c) */ put_tag(pb, "tkhd"); put_be32(pb, 0xf); /* version & flags (track enabled) */ put_be32(pb, track->time); /* creation time */ put_be32(pb, track->time); /* modification time */ put_be32(pb, track->trackID); /* track-id */ put_be32(pb, 0); /* reserved */ maxTrackLenTemp = ((int64_t)globalTimescale*(int64_t)track->trackDuration)/(int64_t)track->timescale; put_be32(pb, (long)maxTrackLenTemp); /* duration */ put_be32(pb, 0); /* reserved */ put_be32(pb, 0); /* reserved */ put_be32(pb, 0x0); /* reserved (Layer & Alternate group) */ /* Volume, only for audio */ if(track->enc->codec_type == CODEC_TYPE_AUDIO) put_be16(pb, 0x0100); else put_be16(pb, 0); put_be16(pb, 0); /* reserved */ /* Matrix structure */ put_be32(pb, 0x00010000); /* reserved */ put_be32(pb, 0x0); /* reserved */ put_be32(pb, 0x0); /* reserved */ put_be32(pb, 0x0); /* reserved */ put_be32(pb, 0x00010000); /* reserved */ put_be32(pb, 0x0); /* reserved */ put_be32(pb, 0x0); /* reserved */ put_be32(pb, 0x0); /* reserved */ put_be32(pb, 0x40000000); /* reserved */ /* Track width and height, for visual only */ if(track->enc->codec_type == CODEC_TYPE_VIDEO) { double sample_aspect_ratio = av_q2d(track->enc->sample_aspect_ratio); if( !sample_aspect_ratio ) sample_aspect_ratio = 1; put_be32(pb, sample_aspect_ratio * track->enc->width*0x10000); put_be32(pb, track->enc->height*0x10000); } else { put_be32(pb, 0); put_be32(pb, 0); } return 0x5c;}static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack* track){ int pos = url_ftell(pb); put_be32(pb, 0); /* size */ put_tag(pb, "trak"); mov_write_tkhd_tag(pb, track); mov_write_mdia_tag(pb, track); return updateSize(pb, pos);}/* TODO: Not sorted out, but not necessary either */static int mov_write_iods_tag(ByteIOContext *pb, MOVContext *mov){ put_be32(pb, 0x15); /* size */ put_tag(pb, "iods"); put_be32(pb, 0); /* version & flags */ put_be16(pb, 0x1007); put_byte(pb, 0); put_be16(pb, 0x4fff); put_be16(pb, 0xfffe); put_be16(pb, 0x01ff); return 0x15;}static int mov_write_mvhd_tag(ByteIOContext *pb, MOVContext *mov){ int maxTrackID = 1, maxTrackLen = 0, i; int64_t maxTrackLenTemp; put_be32(pb, 0x6c); /* size (always 0x6c) */ put_tag(pb, "mvhd"); put_be32(pb, 0); /* version & flags */ put_be32(pb, mov->time); /* creation time */ put_be32(pb, mov->time); /* modification time */ put_be32(pb, mov->timescale); /* timescale */ for (i=0; i<MAX_STREAMS; i++) { if(mov->tracks[i].entry > 0) { maxTrackLenTemp = ((int64_t)globalTimescale*(int64_t)mov->tracks[i].trackDuration)/(int64_t)mov->tracks[i].timescale; if(maxTrackLen < maxTrackLenTemp) maxTrackLen = maxTrackLenTemp; if(maxTrackID < mov->tracks[i].trackID) maxTrackID = mov->tracks[i].trackID; } } put_be32(pb, maxTrackLen); /* duration of longest track */ put_be32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -