Пример #1
0
void MP4StsdAtom::Read() 
{
    /* do the usual read */
    MP4Atom::Read();

    // check that number of children == entryCount
    MP4Integer32Property* pCount = 
        (MP4Integer32Property*)m_pProperties[2];

    if (m_pChildAtoms.Size() != pCount->GetValue()) {
        VERBOSE_READ(GetVerbosity(),
            printf("Warning: stsd inconsistency with number of entries"));

        /* fix it */
        pCount->SetReadOnly(false);
        pCount->SetValue(m_pChildAtoms.Size());
        pCount->SetReadOnly(true);
    }
}
Пример #2
0
MP4StsdAtom::MP4StsdAtom() 
    : MP4Atom("stsd") 
{
    AddVersionAndFlags();

    MP4Integer32Property* pCount = 
        new MP4Integer32Property("entryCount"); 
    pCount->SetReadOnly();
    AddProperty(pCount);

    ExpectChildAtom("mp4a", Optional, Many);
    ExpectChildAtom("enca", Optional, Many);
    ExpectChildAtom("mp4s", Optional, Many);
    ExpectChildAtom("mp4v", Optional, Many);
    ExpectChildAtom("encv", Optional, Many);
    ExpectChildAtom("rtp ", Optional, Many);
     ExpectChildAtom("samr", Optional, Many); // For AMR-NB
     ExpectChildAtom("sawb", Optional, Many); // For AMR-WB
     ExpectChildAtom("s263", Optional, Many); // For H.263
    ExpectChildAtom("avc1", Optional, Many);
    ExpectChildAtom("alac", Optional, Many);
}
Пример #3
0
MP4FtypAtom::MP4FtypAtom() 
	: MP4Atom("ftyp")
{
	MP4StringProperty* pProp = new MP4StringProperty("majorBrand");
	pProp->SetFixedLength(4);
	AddProperty(pProp); /* 0 */

	AddProperty( /* 1 */
		new MP4Integer32Property("minorVersion"));

	MP4Integer32Property* pCount = 
		new MP4Integer32Property("compatibleBrandsCount"); 
	pCount->SetImplicit();
	AddProperty(pCount); /* 2 */

	MP4TableProperty* pTable = 
		new MP4TableProperty("compatibleBrands", pCount);
	AddProperty(pTable); /* 3 */

	pProp = new MP4StringProperty("brand");
	pProp->SetFixedLength(4);
	pTable->AddProperty(pProp);
}
Пример #4
0
void MP4File::MakeFtypAtom(char* majorBrand, u_int32_t minorVersion, char** supportedBrands, u_int32_t supportedBrandsCount)
{
    bool rewriteNeeded = false;
    u_int32_t currentSupportedBrandsCount;
    u_int32_t i;


    MP4Atom* ftypAtom = m_pRootAtom->FindAtom("ftyp");
    if (ftypAtom == NULL) {
        ftypAtom = InsertChildAtom(m_pRootAtom, "ftyp", 0);
    }
    if (majorBrand == NULL)
        return;
    MP4StringProperty* pMajorBrandProperty;
    if (!ftypAtom->FindProperty(
                "ftyp.majorBrand",
                (MP4Property**)&pMajorBrandProperty))
        return;

    pMajorBrandProperty->SetValue(majorBrand);


    MP4Integer32Property* pMinorVersionProperty;
    if (!ftypAtom->FindProperty(
                "ftype.minorVersion",
                (MP4Property**)&pMinorVersionProperty))
        return;

    pMinorVersionProperty->SetValue(minorVersion);

    MP4Integer32Property* pCompatibleBrandsCountProperty;
    if (!ftypAtom->FindProperty(
                "ftyp.compatibleBrandsCount",
                (MP4Property**)&pCompatibleBrandsCountProperty)) return;

    currentSupportedBrandsCount = pCompatibleBrandsCountProperty->GetValue();

    MP4TableProperty* pCompatibleBrandsProperty;
    if (!ftypAtom->FindProperty(
                "ftyp.compatibleBrands",
                (MP4Property**)&pCompatibleBrandsProperty)) return;

    MP4StringProperty* pBrandProperty = (MP4StringProperty*)
                                        pCompatibleBrandsProperty->GetProperty(0);
    ASSERT(pBrandProperty);

    for (i = 0 ; i < ((currentSupportedBrandsCount > supportedBrandsCount) ? supportedBrandsCount : currentSupportedBrandsCount) ; i++) {
        pBrandProperty->SetValue(supportedBrands[i], i);

    }

    if (i < supportedBrandsCount) {
        for ( ; i < supportedBrandsCount ; i++) {
            pBrandProperty->AddValue(supportedBrands[i]);
        }
    }

    if (currentSupportedBrandsCount != supportedBrandsCount) {
        rewriteNeeded = true;
        pBrandProperty->SetCount(supportedBrandsCount);
        pCompatibleBrandsCountProperty->SetReadOnly(false);
        pCompatibleBrandsCountProperty->SetValue(supportedBrandsCount);
        pCompatibleBrandsCountProperty->SetReadOnly(true);
    }

}
Пример #5
0
MP4Track::MP4Track(MP4File* pFile, MP4Atom* pTrakAtom) 
{
	m_pFile = pFile;
	m_pTrakAtom = pTrakAtom;

	m_lastStsdIndex = 0;
	m_lastSampleFile = NULL;

	m_cachedReadSampleId = MP4_INVALID_SAMPLE_ID;
	m_pCachedReadSample = NULL;
	m_cachedReadSampleSize = 0;

	m_writeSampleId = 1;
	m_fixedSampleDuration = 0;
	m_pChunkBuffer = NULL;
	m_chunkBufferSize = 0;
	m_chunkSamples = 0;
	m_chunkDuration = 0;

	m_samplesPerChunk = 0;
	m_durationPerChunk = 0;

	bool success = true;

	MP4Integer32Property* pTrackIdProperty;
	success &= m_pTrakAtom->FindProperty(
		"trak.tkhd.trackId",
		(MP4Property**)&pTrackIdProperty);
	if (success) {
		m_trackId = pTrackIdProperty->GetValue();
	}

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.mdhd.timeScale", 
		(MP4Property**)&m_pTimeScaleProperty);
	if (success) {
		// default chunking is 1 second of samples
		m_durationPerChunk = m_pTimeScaleProperty->GetValue();
	}

	success &= m_pTrakAtom->FindProperty(
		"trak.tkhd.duration", 
		(MP4Property**)&m_pTrackDurationProperty);

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.mdhd.duration", 
		(MP4Property**)&m_pMediaDurationProperty);

	success &= m_pTrakAtom->FindProperty(
		"trak.tkhd.modificationTime", 
		(MP4Property**)&m_pTrackModificationProperty);

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.mdhd.modificationTime", 
		(MP4Property**)&m_pMediaModificationProperty);

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.hdlr.handlerType",
		(MP4Property**)&m_pTypeProperty);

	// get handles on sample size information

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stsz.sampleSize",
		(MP4Property**)&m_pStszFixedSampleSizeProperty);
	
	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stsz.sampleCount",
		(MP4Property**)&m_pStszSampleCountProperty);

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stsz.entries.sampleSize",
		(MP4Property**)&m_pStszSampleSizeProperty);

	// get handles on information needed to map sample id's to file offsets

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stsc.entryCount",
		(MP4Property**)&m_pStscCountProperty);

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stsc.entries.firstChunk",
		(MP4Property**)&m_pStscFirstChunkProperty);

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stsc.entries.samplesPerChunk",
		(MP4Property**)&m_pStscSamplesPerChunkProperty);

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stsc.entries.sampleDescriptionIndex",
		(MP4Property**)&m_pStscSampleDescrIndexProperty);

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stsc.entries.firstSample",
		(MP4Property**)&m_pStscFirstSampleProperty);

	bool haveStco = m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stco.entryCount",
		(MP4Property**)&m_pChunkCountProperty);

	if (haveStco) {
		success &= m_pTrakAtom->FindProperty(
			"trak.mdia.minf.stbl.stco.entries.chunkOffset",
			(MP4Property**)&m_pChunkOffsetProperty);
	} else {
		success &= m_pTrakAtom->FindProperty(
			"trak.mdia.minf.stbl.co64.entryCount",
			(MP4Property**)&m_pChunkCountProperty);

		success &= m_pTrakAtom->FindProperty(
			"trak.mdia.minf.stbl.co64.entries.chunkOffset",
			(MP4Property**)&m_pChunkOffsetProperty);
	}

	// get handles on sample timing info

	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stts.entryCount",
		(MP4Property**)&m_pSttsCountProperty);
	
	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stts.entries.sampleCount",
		(MP4Property**)&m_pSttsSampleCountProperty);
	
	success &= m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stts.entries.sampleDelta",
		(MP4Property**)&m_pSttsSampleDeltaProperty);
	
	// get handles on rendering offset info if it exists

	m_pCttsCountProperty = NULL;
	m_pCttsSampleCountProperty = NULL;
	m_pCttsSampleOffsetProperty = NULL;

	bool haveCtts = m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.ctts.entryCount",
		(MP4Property**)&m_pCttsCountProperty);

	if (haveCtts) {
		success &= m_pTrakAtom->FindProperty(
			"trak.mdia.minf.stbl.ctts.entries.sampleCount",
			(MP4Property**)&m_pCttsSampleCountProperty);

		success &= m_pTrakAtom->FindProperty(
			"trak.mdia.minf.stbl.ctts.entries.sampleOffset",
			(MP4Property**)&m_pCttsSampleOffsetProperty);
	}

	// get handles on sync sample info if it exists

	m_pStssCountProperty = NULL;
	m_pStssSampleProperty = NULL;

	bool haveStss = m_pTrakAtom->FindProperty(
		"trak.mdia.minf.stbl.stss.entryCount",
		(MP4Property**)&m_pStssCountProperty);

	if (haveStss) {
		success &= m_pTrakAtom->FindProperty(
			"trak.mdia.minf.stbl.stss.entries.sampleNumber",
			(MP4Property**)&m_pStssSampleProperty);
	}

	// edit list
	InitEditListProperties();

	// was everything found?
	if (!success) {
		throw new MP4Error("invalid track", "MP4Track::MP4Track");
	}
}