📄 about_hint_tracks.txt
字号:
This is a short description of RTP hint tracks that I createdwhile I was working on L16 and Mpeg1/2 hint tracks.Hint tracks are a series of instructions in a mp4 container file thattell a server how to transmit packets. Hint tracks always referto another track, most likely an audio or video media track. This series of instructions tells the server when to send the packet, what type of RTP header to add, if there is any extra data in thepacket, and how much data to send in the packet. To save on space, a hint can contain a pointer to the media track, instead of duplicatingthat data.It will also tell what SDP to add for the track that is referenced.So, a file that is hinted should have a media track, and an associatedhint track for that media track. There are some mp4 container filesthat just have hint tracks - these are called "fat hints" and areusually not playable locally. These are illegal in ISMA, so we won'ttalk about them.To create hint tracks for a mp4 file is fairly simple with the mp4creatorprogram. Just execute the: mp4creator -hint=<track to hint track number> [-p <payload>] <mp4file>For example:[wmay@wmaytclinux2 content]$ mp4info xvid.mp4 mp4info version 0.9.5.4xvid.mp4:Track Type Info1 video MPEG-4 Simple @ L3, 3.695 secs, 627 kbps, 608x256 @ 23.00 fps2 od Object Descriptors3 scene BIFSI would execute the: mp4creator -hint=1 xvid.mp4and get:[wmay@wmaytclinux2 content]$ mp4info xvid.mp4 mp4info version 0.9.5.4xvid.mp4:Track Type Info1 video MPEG-4 Simple @ L3, 3.695 secs, 627 kbps, 608x256 @ 23.00 fps2 od Object Descriptors3 scene BIFS4 hint Payload MP4V-ES for track 1-----------------------------------------------------------------------------Now a bit about the internals of creating a hint track, for example, if youhave your own codec and want to create a hint track for it.The mp4v2 library has a complete set of functions that will allow youto create a hint track.---- The first function is MP4AddHintTrack:MP4TrackId MP4AddHintTrack(MP4FileHandle hFile, MP4TrackId refTrackId);hFile is the file handle, refTrackId is the track ID that you want toadd the hint for. The return value is the hint track ID that you willuse in the below functions.----The next step is to set the RTP Payload type for the track. The followingfunction does that:bool MP4SetHintTrackRtpPayload( MP4FileHandle hFile, MP4TrackId hintTrackId, const char* pPayloadName, u_int8_t* pPayloadNumber, u_int16_t maxPayloadSize DEFAULT(0), const char *encode_params DEFAULT(NULL));pPayloadName should be the payload type that will be shown in thea=rtpmap statment.pPayloadNumber should most likely be MP4_SET_DYNAMIC_PAYLOAD (which will indicate a dynamic payload number), unless you have a payload defined in rfc 1890. The return value (it is a pointer) will be the dynamicvalue.maxPayloadSize will be the RTP payload size.encode params are basically the channel number in the rtp map, if needed.This will create the "m=" "a=rtpmap:<payload num> <pPayloadName>/<track timescale>[/<encoding params>]"along with some other SDP for the media.---Now, we need to add a series of RtpHint and RtpPacket calls for each samplein the media. Most functions will call MP4ReadSample for each of thesamples in the reference track (MP4GetTrackNumberOfSamples).MP4AddRtpHint or MP4AddRtpVideoHint is called each time the servershould generate a new RTP Timestamp.MP4AddRtpPacket is called for each RTP packet to be added.When all information about the hint is called, MP4WriteRtpHint is called.For example, if a video sample will span multiple packets, the calls mightlook like this: MP4AddRtpHint() MP4AddRtpPacket() ... MP4AddRtpPacket() ... MP4AddRtpPacket() ... MP4WriteRtpHint()Or if you've got sample based audio (not frame based), the calls might look like: MP4AddRtpHint() MP4AddRtpPacket() MP4WriteRtpHint() MP4AddRtpHint() MP4AddRtpPacket() MP4WriteRtpHint() Let's look at each call in detail:bool MP4AddRtpHint( MP4FileHandle hFile, MP4TrackId hintTrackId);is fairly simple.bool MP4AddRtpPacket(MP4FileHandle hFile, MP4TrackId hintTrackId, bool setMbit DEFAULT(false), int32_t transmitOffset DEFAULT(0));is also pretty simple. setMbit is to set the M bit in the RTPheader. transmitOffset is more of an advance topic - it's used tochange the offset in the case of B frames - see the code in rfcisma.cpp for more information.bool MP4WriteRtpHint(MP4FileHandle hFile, MP4TrackId hintTrackId, MP4Duration duration, bool isSyncSample DEFAULT(true));where duration is the number of ticks in the timescale of the hint trackinvolved in this RtpHint, and isSyncSample would be TRUE for sync samples, like I frames.----But what about data for the packets, you ask ? Well there are acouple of functions for that.bool MP4AddRtpImmediateData(MP4FileHandle hFile, MP4TrackId hintTrackId, const u_int8_t* pBytes, u_int32_t numBytes);can be used to add numBytes located at pBytes to the RTP packet. Thiscould be used for a codec specific RTP payload.bool MP4AddRtpSampleData(MP4FileHandle hFile, MP4TrackId hintTrackId, MP4SampleId sampleId, u_int32_t dataOffset, u_int32_t dataLength);is used to create a pointer to the reference track. It creates apointer to the sampleId given, at the dataOffset for dataLength bytes.So, let's say we want to write a series of maxPayloadSize packets.We might do something like: MP4AddRtpHint(); offset = 0; while (sampleSize > 0) { size_to_write = MIN(maxPayloadSize, sampleSize); // mbit is 0 except for last packet for timestamp MP4AddRtpPacket(file, hintTrack, (size_to_write == SampleSize) ? 1 : 0); MP4AddRtpSampleData(file, hintTrack, sampleId, offset, size_to_write); offset += size_to_write; sampleSize -= size_to_write; } MP4WriteRtpHint(file, hintTrack, <duration>, isSyncSample);In the above, we may read into the sample to add immediate data.Or if we want to pack several frames in a packet, we might do: sampleId = 1; // note 1 based sample id's offset = 0; while (sampleId <= MP4GetTrackNumberOfSamples(file, trackId)) { if (offset == 0) { MP4AddRtpHint(); MP4AddRtpPacket(); } size_to_write = MP4GetSampleSize(file, sampleId); if (size_to_write + offset < maxPayloadSize) { MP4AddSampleData(file, hintTrack, sampleId, offset, size_to_write); sampleId++; offset += size_to_write; } else { MP4WriteRtpHint(file, hintTrack, duration of added tracks); offset = 0; } } There are many variations on the above 2 examples. See the files:lib/mp4av/l16.cpp mpeg3.cpp rfcisma.cpp rfc2250.cpp rfc3119.cpp rfc3016.cppFor more information and more ideas.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -