Пример #1
0
void MP4File::CreateIsmaODUpdateCommandFromFileForStream(
    MP4TrackId audioTrackId,
    MP4TrackId videoTrackId,
    u_int8_t** ppBytes,
    u_int64_t* pNumBytes)
{
    MP4DescriptorProperty* pAudioEsd = NULL;
    MP4Integer8Property* pAudioSLConfigPredef = NULL;
    MP4BitfieldProperty* pAudioAccessUnitEndFlag = NULL;
    int oldAudioUnitEndFlagValue = 0;
    MP4DescriptorProperty* pVideoEsd = NULL;
    MP4Integer8Property* pVideoSLConfigPredef = NULL;
    MP4BitfieldProperty* pVideoAccessUnitEndFlag = NULL;
    int oldVideoUnitEndFlagValue = 0;
    MP4IntegerProperty* pAudioEsdId = NULL;
    MP4IntegerProperty* pVideoEsdId = NULL;

    if (audioTrackId != MP4_INVALID_TRACK_ID) {
        // changed mp4a to * to handle enca case
        MP4Atom* pEsdsAtom =
            FindAtom(MakeTrackName(audioTrackId,
                                   "mdia.minf.stbl.stsd.*.esds"));
        ASSERT(pEsdsAtom);

        pAudioEsd = (MP4DescriptorProperty*)(pEsdsAtom->GetProperty(2));
        // ESID is 0 for file, stream needs to be non-ze
        pAudioEsd->FindProperty("ESID",
                                (MP4Property**)&pAudioEsdId);

        ASSERT(pAudioEsdId);
        pAudioEsdId->SetValue(audioTrackId);

        // SL config needs to change from 2 (file) to 1 (null)
        pAudioEsd->FindProperty("slConfigDescr.predefined",
                                (MP4Property**)&pAudioSLConfigPredef);
        ASSERT(pAudioSLConfigPredef);
        pAudioSLConfigPredef->SetValue(0);

        pAudioEsd->FindProperty("slConfigDescr.useAccessUnitEndFlag",
                                (MP4Property **)&pAudioAccessUnitEndFlag);
        oldAudioUnitEndFlagValue =
            pAudioAccessUnitEndFlag->GetValue();
        pAudioAccessUnitEndFlag->SetValue(1);
    }

    if (videoTrackId != MP4_INVALID_TRACK_ID) {
        // changed mp4v to * to handle encv case
        MP4Atom* pEsdsAtom =
            FindAtom(MakeTrackName(videoTrackId,
                                   "mdia.minf.stbl.stsd.*.esds"));
        ASSERT(pEsdsAtom);

        pVideoEsd = (MP4DescriptorProperty*)(pEsdsAtom->GetProperty(2));
        pVideoEsd->FindProperty("ESID",
                                (MP4Property**)&pVideoEsdId);

        ASSERT(pVideoEsdId);
        pVideoEsdId->SetValue(videoTrackId);

        // SL config needs to change from 2 (file) to 1 (null)
        pVideoEsd->FindProperty("slConfigDescr.predefined",
                                (MP4Property**)&pVideoSLConfigPredef);
        ASSERT(pVideoSLConfigPredef);
        pVideoSLConfigPredef->SetValue(0);

        pVideoEsd->FindProperty("slConfigDescr.useAccessUnitEndFlag",
                                (MP4Property **)&pVideoAccessUnitEndFlag);
        oldVideoUnitEndFlagValue =
            pVideoAccessUnitEndFlag->GetValue();
        pVideoAccessUnitEndFlag->SetValue(1);
    }

    CreateIsmaODUpdateCommandForStream(
        pAudioEsd, pVideoEsd, ppBytes, pNumBytes);
    VERBOSE_ISMA(GetVerbosity(),
                 printf("After CreateImsaODUpdateCommandForStream len %llu =\n", *pNumBytes); MP4HexDump(*ppBytes, *pNumBytes));
    // return SL config values to 2 (file)
    // return ESID values to 0
    if (pAudioSLConfigPredef) {
        pAudioSLConfigPredef->SetValue(2);
    }
    if (pAudioEsdId) {
        pAudioEsdId->SetValue(0);
    }
    if (pAudioAccessUnitEndFlag) {
        pAudioAccessUnitEndFlag->SetValue(oldAudioUnitEndFlagValue );
    }
    if (pVideoEsdId) {
        pVideoEsdId->SetValue(0);
    }
    if (pVideoSLConfigPredef) {
        pVideoSLConfigPredef->SetValue(2);
    }
    if (pVideoAccessUnitEndFlag) {
        pVideoAccessUnitEndFlag->SetValue(oldVideoUnitEndFlagValue );
    }
}
Пример #2
0
void MP4File::CreateIsmaIodFromFile(
    MP4TrackId odTrackId,
    MP4TrackId sceneTrackId,
    MP4TrackId audioTrackId,
    MP4TrackId videoTrackId,
    u_int8_t** ppBytes,
    u_int64_t* pNumBytes)
{
    MP4Descriptor* pIod = new MP4IODescriptor();
    pIod->SetTag(MP4IODescrTag);
    pIod->Generate();

    MP4Atom* pIodsAtom = FindAtom("moov.iods");
    ASSERT(pIodsAtom);
    MP4DescriptorProperty* pSrcIod =
        (MP4DescriptorProperty*)pIodsAtom->GetProperty(2);

    CloneIntegerProperty(pIod, pSrcIod, "objectDescriptorId");
    CloneIntegerProperty(pIod, pSrcIod, "ODProfileLevelId");
    CloneIntegerProperty(pIod, pSrcIod, "sceneProfileLevelId");
    CloneIntegerProperty(pIod, pSrcIod, "audioProfileLevelId");
    CloneIntegerProperty(pIod, pSrcIod, "visualProfileLevelId");
    CloneIntegerProperty(pIod, pSrcIod, "graphicsProfileLevelId");

    // mutate esIds from MP4ESIDIncDescrTag to MP4ESDescrTag
    MP4DescriptorProperty* pEsProperty;
    pIod->FindProperty("esIds", (MP4Property**)&pEsProperty);
    pEsProperty->SetTags(MP4ESDescrTag);

    MP4IntegerProperty* pSetProperty;
    MP4IntegerProperty* pSceneESID;
    MP4IntegerProperty* pOdESID;

    // OD
    MP4Descriptor* pOdEsd =
        pEsProperty->AddDescriptor(MP4ESDescrTag);
    pOdEsd->Generate();

    pOdEsd->FindProperty("ESID",
                         (MP4Property**)&pOdESID);

    // we set the OD ESID to a non-zero unique value
    pOdESID->SetValue(m_odTrackId);

    pOdEsd->FindProperty("URLFlag",
                         (MP4Property**)&pSetProperty);
    pSetProperty->SetValue(1);

    u_int8_t* pBytes;
    u_int64_t numBytes;

    CreateIsmaODUpdateCommandFromFileForStream(
        audioTrackId,
        videoTrackId,
        &pBytes,
        &numBytes);

    VERBOSE_ISMA(GetVerbosity(),
                 printf("OD data =\n"); MP4HexDump(pBytes, numBytes));

    char* odCmdBase64 = MP4ToBase64(pBytes, numBytes);

    char* urlBuf = (char*)MP4Malloc(strlen(odCmdBase64) + 64);

    sprintf(urlBuf,
            "data:application/mpeg4-od-au;base64,%s",
            odCmdBase64);

    MP4StringProperty* pUrlProperty;
    pOdEsd->FindProperty("URL",
                         (MP4Property**)&pUrlProperty);
    pUrlProperty->SetValue(urlBuf);

    VERBOSE_ISMA(GetVerbosity(),
                 printf("OD data URL = \042%s\042\n", urlBuf));

    MP4Free(odCmdBase64);
    odCmdBase64 = NULL;
    MP4Free(pBytes);
    pBytes = NULL;
    MP4Free(urlBuf);
    urlBuf = NULL;

    MP4DescriptorProperty* pSrcDcd = NULL;

    // HACK temporarily point to scene decoder config
    FindProperty(MakeTrackName(odTrackId,
                               "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr"),
                 (MP4Property**)&pSrcDcd);
    ASSERT(pSrcDcd);
    MP4Property* pOrgOdEsdProperty =
        pOdEsd->GetProperty(8);
    pOdEsd->SetProperty(8, pSrcDcd);

    // bufferSizeDB needs to be set appropriately
    MP4BitfieldProperty* pBufferSizeProperty = NULL;
    pOdEsd->FindProperty("decConfigDescr.bufferSizeDB",
                         (MP4Property**)&pBufferSizeProperty);
    ASSERT(pBufferSizeProperty);
    pBufferSizeProperty->SetValue(numBytes);

    // SL config needs to change from 2 (file) to 1 (null)
    pOdEsd->FindProperty("slConfigDescr.predefined",
                         (MP4Property**)&pSetProperty);
    pSetProperty->SetValue(1);


    // Scene
    MP4Descriptor* pSceneEsd =
        pEsProperty->AddDescriptor(MP4ESDescrTag);
    pSceneEsd->Generate();

    pSceneEsd->FindProperty("ESID",
                            (MP4Property**)&pSceneESID);
    // we set the Scene ESID to a non-zero unique value
    pSceneESID->SetValue(sceneTrackId);

    pSceneEsd->FindProperty("URLFlag",
                            (MP4Property**)&pSetProperty);
    pSetProperty->SetValue(1);

    CreateIsmaSceneCommand(
        MP4_IS_VALID_TRACK_ID(audioTrackId),
        MP4_IS_VALID_TRACK_ID(videoTrackId),
        &pBytes,
        &numBytes);

    VERBOSE_ISMA(GetVerbosity(),
                 printf("Scene data =\n"); MP4HexDump(pBytes, numBytes));

    char *sceneCmdBase64 = MP4ToBase64(pBytes, numBytes);

    urlBuf = (char*)MP4Malloc(strlen(sceneCmdBase64) + 64);
    sprintf(urlBuf,
            "data:application/mpeg4-bifs-au;base64,%s",
            sceneCmdBase64);

    pSceneEsd->FindProperty("URL",
                            (MP4Property**)&pUrlProperty);
    pUrlProperty->SetValue(urlBuf);

    VERBOSE_ISMA(GetVerbosity(),
                 printf("Scene data URL = \042%s\042\n", urlBuf));

    MP4Free(sceneCmdBase64);
    sceneCmdBase64 = NULL;
    MP4Free(urlBuf);
    urlBuf = NULL;
    MP4Free(pBytes);
    pBytes = NULL;

    // HACK temporarily point to scene decoder config
    FindProperty(MakeTrackName(sceneTrackId,
                               "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr"),
                 (MP4Property**)&pSrcDcd);
    ASSERT(pSrcDcd);
    MP4Property* pOrgSceneEsdProperty =
        pSceneEsd->GetProperty(8);
    pSceneEsd->SetProperty(8, pSrcDcd);

    // bufferSizeDB needs to be set
    pBufferSizeProperty = NULL;
    pSceneEsd->FindProperty("decConfigDescr.bufferSizeDB",
                            (MP4Property**)&pBufferSizeProperty);
    ASSERT(pBufferSizeProperty);
    pBufferSizeProperty->SetValue(numBytes);

    // SL config needs to change from 2 (file) to 1 (null)
    pSceneEsd->FindProperty("slConfigDescr.predefined",
                            (MP4Property**)&pSetProperty);
    pSetProperty->SetValue(1);


    // finally get the whole thing written to a memory
    pIod->WriteToMemory(this, ppBytes, pNumBytes);


    // now carefully replace esd properties before destroying
    pOdEsd->SetProperty(8, pOrgOdEsdProperty);
    pSceneEsd->SetProperty(8, pOrgSceneEsdProperty);
    pSceneESID->SetValue(0); // restore 0 value
    pOdESID->SetValue(0);

    delete pIod;

    VERBOSE_ISMA(GetVerbosity(),
                 printf("IOD data =\n"); MP4HexDump(*ppBytes, *pNumBytes));
}