Skip to content

Instantly share code, notes, and snippets.

@guinurmi
Last active April 23, 2018 13:57
Show Gist options
  • Save guinurmi/50c61bb4bf3a79f9d30c497b941bab80 to your computer and use it in GitHub Desktop.
Save guinurmi/50c61bb4bf3a79f9d30c497b941bab80 to your computer and use it in GitHub Desktop.
Signaling Changer of AAC in MP4 without Demux

Signaling Changer of AAC in MP4 without Demux

guinurmi

Applying the patch (gpac-v0.6.1.diff), MP4Box becomes to be able to accept -sbr and -ps when importing MP4.
In other words, MP4Box will be able to change signaling of AAC in MP4 without demux which may cause out-of-sync.

> MP4Box -info AVC_HE-AAC.mp4 2>&1 | grep LC
MPEG-4 Audio AAC LC - 2 Channel(s) - SampleRate 24000

> MP4BoxSBR -add AVC_HE-AAC.mp4 -sbr -new new_AVC_HE-AAC.mp4
IsoMedia import AVC_HE-AAC.mp4 - track ID 1 - Video (size 320 x 240)
IsoMedia import AVC_HE-AAC.mp4 - track ID 2 - Audio (SR 24000 - 2 channels)
 - backward compatible signaling of AAC-SBR (SBR-SR 48000)
Saving new_AVC_HE-AAC.mp4: 0.500 secs Interleaving

> MP4Box -info new_AVC_HE-AAC.mp4 2>&1 | grep LC
MPEG-4 Audio AAC LC (HE-AAC v1) - 2 Channel(s) - SampleRate 24000 - SBR: SampleRate 48000 Type MPEG-4 Audio SBR

Let's use this patched MP4Box (MP4BoxSBR) for inflexible hardware players.
MP4BoxSBR.exe was built on MINGW32, so you can execute it without additional DLLs in Windows Command Prompt.

diff --git a/include/gpac/version.h b/include/gpac/version.h
index f93e487..630b220 100644
--- a/include/gpac/version.h
+++ b/include/gpac/version.h
@@ -41,6 +41,6 @@
#define GPAC_VERSION_MICRO 0
#include <gpac/revision.h>
-#define GPAC_FULL_VERSION GPAC_VERSION "-rev" GPAC_GIT_REVISION
+#define GPAC_FULL_VERSION GPAC_VERSION "-rev" GPAC_GIT_REVISION " (-sbr usable when importing MP4)"
#endif //_GF_VERSION_H
diff --git a/src/media_tools/media_import.c b/src/media_tools/media_import.c
index 783df49..4786942 100644
--- a/src/media_tools/media_import.c
+++ b/src/media_tools/media_import.c
@@ -2023,6 +2023,7 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import)
GF_Err e;
u64 offset, sampDTS, duration, dts_offset;
u32 track, di, trackID, track_in, i, num_samples, mtype, w, h, sr, sbr_sr, ch, mstype, cur_extract_mode;
+ u32 bot = 0, bsi = 0;
s32 trans_x, trans_y;
s16 layer;
u8 bps;
@@ -2114,6 +2115,8 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import)
PL = dsi.audioPL;
sbr = dsi.has_sbr ? ((dsi.base_object_type==GF_M4A_AAC_SBR || dsi.base_object_type==GF_M4A_AAC_PS) ? 2 : 1) : GF_FALSE;
ps = dsi.has_ps;
+ bot = dsi.base_object_type;
+ bsi = dsi.base_sr_index;
}
#endif
gf_isom_set_pl_indication(import->dest, GF_ISOM_PL_AUDIO, PL);
@@ -2330,6 +2333,53 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import)
}
}
+ if (origin_esd && (origin_esd->decoderConfig->objectTypeIndication==GPAC_OTI_AUDIO_AAC_MPEG4)
+ && ((import->flags & GF_IMPORT_SBR_IMPLICIT) || (import->flags & GF_IMPORT_PS_IMPLICIT))) {
+ u16 sbr_sr_idx = 0;
+ GF_BitStream *dsi;
+ dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
+
+ for (i=0; i<16; i++) {
+ if (GF_M4ASampleRates[i] == (u32) 2*sr) {
+ sbr_sr_idx = i;
+ break;
+ }
+ }
+
+ /*regular AAC*/
+ gf_bs_write_int(dsi, bot, 5);
+ gf_bs_write_int(dsi, bsi, 4);
+ gf_bs_write_int(dsi, ch, 4);
+ gf_bs_align(dsi);
+ /*implicit AAC SBR signal*/
+ if (import->flags & GF_IMPORT_SBR_IMPLICIT) {
+ gf_import_message(import, GF_OK, " - backward compatible signaling of AAC-SBR (SBR-SR %d)", 2*sr);
+ gf_bs_write_int(dsi, 0x2b7, 11); /*sync extension type*/
+ gf_bs_write_int(dsi, 5, 5); /*SBR objectType*/
+ gf_bs_write_int(dsi, 1, 1); /*SBR present flag*/
+ gf_bs_write_int(dsi, sbr_sr_idx, 4);
+ }
+ if (import->flags & GF_IMPORT_PS_IMPLICIT) {
+ gf_import_message(import, GF_OK, " - backward compatible signaling of AAC-PS");
+ gf_bs_write_int(dsi, 0x548, 11); /*sync extension type*/
+ gf_bs_write_int(dsi, 1, 1); /* PS present flag */
+ }
+ gf_bs_align(dsi);
+
+ {
+ GF_ESD *esd = gf_isom_get_esd(import->dest, track, 1);
+ if (esd) {
+ if (!esd->decoderConfig->decoderSpecificInfo) esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG);
+ if (esd->decoderConfig->decoderSpecificInfo->data) gf_free(esd->decoderConfig->decoderSpecificInfo->data);
+ gf_bs_get_content(dsi, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength);
+ gf_isom_change_mpeg4_description(import->dest, track, 1, esd);
+ esd->decoderConfig->decoderSpecificInfo->data = NULL;
+ gf_odf_desc_del((GF_Descriptor *)esd);
+ }
+ }
+ gf_bs_del(dsi);
+ }
+
gf_media_update_bitrate(import->dest, track);
exit:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment