Log in

View Full Version : latest changes in MP4box/ GPAC


Bluedan
13th March 2005, 14:55
latest CVS update 08/03/05:
- rewrote AMR hinter for RTP agregation, added maxptime hint param for speech rtp payloads (AMR/QCELP/EVRC/SMV).
- changed SBR import in MP4Box: -sbr for backward compatible HE-AAC (implicit) signaling, -sbrx for non-backward compatible (explicit) signaling.
- fixed 3GP5 vs 3GP6 file brands
- added bandwidth signaling in SDP (b=AS:X) for some players compatibility
- added H263 and MPEG4 Visual(CMP) importers in MP4Box
- added extra SDP lines support in MP4Box - PLEASE refer to rfc2327 before complaining :)

This is the changelog taken from C_Ds file shack mirror (http://www.aziendeassociate.it/cd.asp?dir=/gpac/dev).
The respective files are also found there.

Who is able to explain the highlighted phrases to me?
AFAIRemember since v0.23 HE-AAC muxed with MP4box was always correctly signalled as HE-AAC in DS based apps according to what CoreAAC showed.

bond
13th March 2005, 19:29
Originally posted by Bluedan
Who is able to explain the highlighted phrases to me?
AFAIRemember since v0.23 HE-AAC muxed with MP4box was always correctly signalled as HE-AAC in DS based apps according to what CoreAAC showedthere are three ways for signalling he-aac in .mp4 defined by the specs:
1) dont signal it at all (when you dont use -sbr/-sbrx in mp4box) and let the decoder detect sbr on its own
2) signal lc-aac in iod but he-aac somewhere else (with -sbr), so that a he-aac decoder easily detects sbr but a non he-aac decoder can also play the file
3) signal he-aac in iod (with -sbrx), which means that only he-aac decoders should be able to play the file (which of course also makes sense, as he-aac decoded with a lc-aac decoder sounds crap)

Bluedan
13th March 2005, 20:00
Ah, well. Thanks for explanation.

The 3rd (new in MP4box) point sounds reasonable.
Allthough, at least in the PC-world I think the situation does not demand this, for available and whide-spread DirectShow based decoders such as Nero, CoreAAC, ffdshow, ... can all handle HE-AAC signalled streams.
And OSMO as systems player should also.
But of course this is not measured everything hires. ;)
Could a splitter mess with the signaling, if it was badly written, so that for situation N°2 the HE signaling (stored "somewhere else") could be lost?

Don't mistake me, I'm just trying to find out when this function could be useful.

BTW, what is "iod"?

bond
13th March 2005, 20:31
Originally posted by Bluedan
The 3rd (new in MP4box) point sounds reasonable.
Allthough, at least in the PC-world I think the situation does not demand this, for available and whide-spread DirectShow based decoders such as Nero, CoreAAC, ffdshow, ... can all handle HE-AAC signalled streams.
And OSMO as systems player should also.indeed :)

Could a splitter mess with the signaling, if it was badly written, so that for situation N°2 the HE signaling (stored "somewhere else") could be lost?hm, i am not sure, but i dont think that is likely to happen

BTW, what is "iod"?an atom which is used for storing the profiles/levels

Bluedan
13th March 2005, 21:12
OK.
Concerning SDP I've found this (http://ftp.shlink.de/dokumente/rfc/rfc2327.txt) via google.
So this acronym obviously dissolves to Session Description Protocol.
As far as I understand it deals with internet mutimedia conferences and mp4 is affected if used in this context.
See extract below.

Abstract
This document defines the Session Description Protocol, SDP.
SDP is intended for describing multimedia sessions for the purposes of session announcement, session invitation, and other forms of multimedia session initiation.
This document is a product of the Multiparty Multimedia Session Control (MMUSIC) working group of the Internet Engineering Task Force. Comments are solicited and should be addressed to the working group's mailing list at confctrl@isi.edu and/or the authors.

1. Introduction
On the Internet multicast backbone (Mbone), a session directory tool is used to advertise multimedia conferences and communicate the conference addresses and conference tool-specific information necessary for participation.
This document defines a session description protocol for this purpose, and for general real-time multimedia session description purposes. This memo does not describe multicast address allocation or the distribution of SDP messages in detail.
These are described in accompanying memos.
SDP is not intended for negotiation of media encodings.

Drachir
21st March 2005, 22:32
The IOD (InitialObjectDescriptor) isn't only there to store profiles/levels. It contains information how to decode the other tracks inside the MP4 file. The IOD should be the starting point for the player how to play MP4 files. But many player simply ignore the IOD. From the IOD you will get the ES-Descriptor for the SceneDrscriptionStream (BIFS Track) and ES-Descriptor for ObjectDescriptorStream. The BIFS Track contains information how the individual streams inside the MP4 file will get presented. The OD (ObjectDescriptorStream) contains the ES-Descriptor for the A/V objects which are mentioned in SceneDescriptionStream.

A simple MP4 File with one audio and one video track look this way(BIFS Text):

#IOD START
InitialObjectDescriptor {
objectDescriptorID 1
audioProfileLevelIndication 44
visualProfileLevelIndication 254
sceneProfileLevelIndication 1
graphicsProfileLevelIndication 1
ODProfileLevelIndication 1
esDescr [
ES_Descriptor { #for BIFS Track
ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 2
streamType 3
bufferSizeDB 3
decSpecificInfo BIFSv2Config {
isCommandStream true
pixelMetric true
pixelWidth 320
pixelHeight 240
}
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useTimeStampsFlag true
timeStampResolution 600
timeStampLength 32
}
}
ES_Descriptor { #for OD Track
ES_ID 2
OCR_ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 1
streamType 1
bufferSizeDB 137
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useTimeStampsFlag true
timeStampResolution 600
timeStampLength 32
}
}
]
}#IOD END

#BIFS Track Start
OrderedGroup {
children [
Sound2D {
source AudioSource {
url [od:10]
}
}
Shape {
appearance Appearance {
texture MovieTexture {
url [od:20]
}
}
geometry Bitmap {}

}
]
}
#BIFS Track End

#OD Track Start
RAP AT 0 {
UPDATE OD [
ObjectDescriptor {
objectDescriptorID 20
esDescr [
ES_Descriptor {
ES_ID 201
OCR_ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 33 #0x21 AVC/H264
streamType 4 #Visual
bufferSizeDB 12042
maxBitrate 521136
avgBitrate 299024
decSpecificInfo DecoderSpecificInfo {
info %01%4D%00%28%FD%E1%00%18%67%4D%00%28%9A%76%0A%0F%9F%F8%00%78%00%80%80%00%00%03%00%80%00%00%0C%C2%01%00%04%68%EE%3C%80
}
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useRandomAccessPointFlag true
useTimeStampsFlag true
timeStampResolution 25000
timeStampLength 32
}
muxInfo MuxInfo {
fileName "file.mp4#201"
streamFormat "MP4"
}
}
]
}
ObjectDescriptor {
objectDescriptorID 10
esDescr [
ES_Descriptor {
ES_ID 101
OCR_ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 64 #Mpeg4 Audio
streamType 5 #Audio
bufferSizeDB 959
maxBitrate 136360
avgBitrate 127648
decSpecificInfo DecoderSpecificInfo {
info %2B%92%08
}
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useTimeStampsFlag true
timeStampResolution 22050
timeStampLength 32
}
muxInfo MuxInfo {
fileName "file.mp4#101"
streamFormat "MP4"
}
}
]
}
]
}#OD Track End

If you create a MP4 file with MP4Box with more than one audio/video stream you will just get an empty IOD - only with profiles/levels. You can't create the correct IOD/BIFS/OD with "MP4Box -isma yourfile.mp4" because ISMA don't support more than one audio/video track. If your are not happy with it you have to create your self a BIFS text (*.bt) file and from this with "MP4Box -inter 500 -mp4 yourBIFSText.bt" the correct MP4 File. You could ask your self - do I really need IOD/BIFS/OD ? Hmm - but what is than the difference from a 3GP file to your created MP4 File? 3GP files don't have an IOD/BIFS or OD track.

Let see how Nero (NVE-3.1.0.0) ist doing MP4 files with 2 audio tracks. "MP4Box -bt NERO_3.1.0.0.mp4":


#IOD START
InitialObjectDescriptor {
objectDescriptorID 1
audioProfileLevelIndication 2
visualProfileLevelIndication 245
sceneProfileLevelIndication 1
graphicsProfileLevelIndication 254
ODProfileLevelIndication 254
esDescr [
ES_Descriptor {
ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 1
streamType 1
bufferSizeDB 40
maxBitrate 320
avgBitrate 320
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useTimeStampsFlag true
timeStampResolution 1000
timeStampLength 32
}
}
ES_Descriptor {
ES_ID 2
OCR_ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 1
streamType 3
bufferSizeDB 36
maxBitrate 288
avgBitrate 288
decSpecificInfo BIFSConfig {
nodeIDbits 10
routeIDbits 10
isCommandStream true
pixelMetric true
pixelWidth 704
pixelHeight 544
}
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useTimeStampsFlag true
timeStampResolution 1000
timeStampLength 32
}
}
]
}#IOD END

#SCENE
OrderedGroup {
children [
Shape {
appearance Appearance {
texture MovieTexture {
url [od:10]
}
}
geometry Bitmap {
scale 1 1
}
}
Switch {
whichChoice 0 #use first case1
choice [
Sound2D { #case1
source AudioClip {
url [od:20]
}
}
Sound2D { #case2
source AudioClip {
url [od:30]
}
}
]
}
]
}#SCENE END

#OD START
RAP AT 0 {
UPDATE OD [
ObjectDescriptor {
objectDescriptorID 10
esDescr [
ES_Descriptor {
ES_ID 3
OCR_ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 32 #MPEG 4 Visual
streamType 4 #Visual
bufferSizeDB 153794
maxBitrate 4563664
avgBitrate 3130283
decSpecificInfo DecoderSpecificInfo {
info %00%00%01%B0%F5%00%00%01%B5%09%00%00%01%00%00%00%01%20%08%C4%8D%40%00%4F%B1%40%7A%C8%05%87%21%96%1A%8C%1F%44%58%11%10%51%8F%00%00%01%B2%65%6D%34%76%20%34%2E%31%2E%36%2E%35%00%C2%FF
}
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useRandomAccessPointFlag true
useTimeStampsFlag true
timeStampResolution 25000
timeStampLength 32
}
muxInfo MuxInfo {
fileName "NERO_3.1.0.0.mp4#3"
streamFormat "MP4"
}
}
]
}
ObjectDescriptor {
objectDescriptorID 20
esDescr [
ES_Descriptor {
ES_ID 4
OCR_ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 64 #MPEG4Audio
streamType 5 #Audio
bufferSizeDB 671
maxBitrate 84456
avgBitrate 79773
decSpecificInfo DecoderSpecificInfo {
info %12%10
}
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useTimeStampsFlag true
timeStampResolution 44100
timeStampLength 32
}
muxInfo MuxInfo {
fileName "NERO_3.1.0.0.mp4#4"
streamFormat "MP4"
}
}
]
}
ObjectDescriptor {
objectDescriptorID 30
esDescr [
ES_Descriptor {
ES_ID 5
OCR_ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 64 #MPEG4Audio
streamType 5 #Audio
bufferSizeDB 676
maxBitrate 83856
avgBitrate 79911
decSpecificInfo DecoderSpecificInfo {
info %12%10
}
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useTimeStampsFlag true
timeStampResolution 44100
timeStampLength 32
}
muxInfo MuxInfo {
fileName "NERO_3.1.0.0.mp4#5"
streamFormat "MP4"
}
}
]
}
]
}#OD END


The way Nero do this is possible but not the best way. First in the SceneDescription is nothing that let you select the second case. If you change "whichChoice 0" to "whichChoice 1" the second audio stream will played. Ok you will do this with your player which dosen't take into attention the BIFS (IOD/OD) track. It is more elegant to use only one Sound2D and change the URL from [od:20]to [od:30] if you want play the other stream. Like here:


#IOD START
InitialObjectDescriptor {
objectDescriptorID 1
audioProfileLevelIndication 41
visualProfileLevelIndication 245
sceneProfileLevelIndication 254
graphicsProfileLevelIndication 1
ODProfileLevelIndication 1
esDescr [
ES_Descriptor {
ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 2
streamType 3
bufferSizeDB 80
decSpecificInfo BIFSv2Config {
isCommandStream true
pixelMetric true
pixelWidth 640 # define here the width of the input video
pixelHeight 352 # define here the height of the input video
}
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useTimeStampsFlag true
timeStampResolution 600
timeStampLength 32
}
}
ES_Descriptor {
ES_ID 2
OCR_ES_ID 1
decConfigDescr DecoderConfigDescriptor {
objectTypeIndication 1
streamType 1
bufferSizeDB 167
}
slConfigDescr SLConfigDescriptor {
useAccessUnitStartFlag true
useAccessUnitEndFlag true
useTimeStampsFlag true
timeStampResolution 600
timeStampLength 32
}
}
]
}#IOD END

#SCENE START (BIFS Track)
OrderedGroup {
children [
Background2D {
backColor 0 0 0
}
DEF SW1 Switch {
whichChoice 0
choice [
OrderedGroup {}
OrderedGroup {
children [
Sound2D {
source DEF Audio AudioSource {
url [od:20]
}
}
Shape {
appearance Appearance {
texture MovieTexture {
url [od:10]
}
}
geometry Bitmap {}

}
DEF TS3 TouchSensor {}
]
}
]
}
DEF SW2 Switch {
whichChoice 0
choice [
OrderedGroup {
children [
Transform2D {
children [
Shape {
appearance Appearance {
material Material2D {
emissiveColor 0 0 0
filled TRUE
}
}
geometry Rectangle {
size 195 135
}
}
]
}
Transform2D {
translation 0 30
children [
Shape {
appearance Appearance {
material Material2D {
emissiveColor 1 1 1
filled TRUE
}
}
geometry Rectangle {
size 170 55
}
}
]
}
Transform2D {
translation 0 -30
children [
Shape {
appearance Appearance {
material Material2D {
emissiveColor 1 1 1
filled TRUE
}
}
geometry Rectangle {
size 170 55
}
}
]
}
Transform2D {
translation 0 30
children [
Shape {
appearance Appearance {
material Material2D {
emissiveColor 0 0 0
filled TRUE
}
}
geometry Rectangle {
size 167 52
}
}
Transform2D {
translation 0 -10
children [
Shape {
appearance Appearance {
material Material2D {
emissiveColor 1 1 1
filled TRUE
}
}
geometry Text {
string ["AudioStream1"] #replace AudioStream1 by the language
fontStyle FontStyle {
justify ["MIDDLE"]
size 20
}
}
}
]
}
DEF TS1 TouchSensor {}
]
}
Transform2D {
translation 0 -30
children [
Shape {
appearance Appearance {
material Material2D {
emissiveColor 0 0 0
filled TRUE
}
}
geometry Rectangle {
size 167 52
}
}
Transform2D {
translation 0 -10
children [
Shape {
appearance Appearance {
material Material2D {
emissiveColor 1 1 1
filled TRUE
}
}
geometry Text {
string ["AudioStream2"] #replace AudioStream2 by the language
fontStyle FontStyle {
justify ["MIDDLE"]
size 20
}
}
}
]
}
DEF TS2 TouchSensor {}
]
}
]
}
OrderedGroup {}
]
}
DEF PlayAudio1 Conditional {
buffer {
REPLACE SW1.whichChoice BY 1
REPLACE SW2.whichChoice BY 1
REPLACE Audio.url BY [od:20]
}
}
DEF PlayAudio2 Conditional {
buffer {
REPLACE SW1.whichChoice BY 1
REPLACE SW2.whichChoice BY 1
REPLACE Audio.url BY [od:30]
}
}
DEF ShowAudioMenue Conditional {
buffer {
REPLACE SW2.whichChoice BY 0
}
}
]
}

ROUTE TS1.isActive TO PlayAudio1.activate
ROUTE TS2.isActive TO PlayAudio2.activate
ROUTE TS3.isActive TO ShowAudioMenue.activate
#SCENE END


#OD Track START
AT 0 {
UPDATE OD [
ObjectDescriptor {
objectDescriptorID 10
esDescr [
ES_Descriptor {
ES_ID 3
OCR_ES_ID 1
muxInfo MuxInfo {
fileName "video.avi#video" # the "#video" defines that you take the video stream (#audio would take the audio stream (mp3))
# fileName "video.mp4#3" # when muxing from mp4 as input you always have to define the trackID of the stream!
# fileName "video.ogg#video
}
}
]
}
ObjectDescriptor {
objectDescriptorID 20
esDescr [
ES_Descriptor {
ES_ID 4
OCR_ES_ID 1
muxInfo MuxInfo {
fileName "audioStream1.aac"
# fileName "audioStream1.mp3"
# fileName "audioStream1.avi#audio"
# fileName "audioStream1.mp4#4
# fileName "audioStream1.ogg#audio
}
}
]
}
ObjectDescriptor {
objectDescriptorID 30
esDescr [
ES_Descriptor {
ES_ID 5
OCR_ES_ID 1
muxInfo MuxInfo {
fileName "audioStream2.aac"
# fileName "audioStream2.mp3"
# fileName "audioStream2.avi#audio"
# fileName "audioStream2.mp4#5
# fileName "audioStream2.ogg#audio
}
}
]
}
]
}#OD Track END