Example #1
0
void MP4D263Atom::Write()
{
    // Check whether we have valid values in the bitr atom
    // (if it exists, of course)
    MP4Atom* bitrAtom = FindAtom("d263.bitr");
    if (bitrAtom) {
        uint32_t avgBitrate;
        uint32_t maxBitrate;

        MP4Integer32Property* pProp;
        bitrAtom->FindProperty("bitr.avgBitrate",
                               (MP4Property**)&pProp,
                               NULL);
        ASSERT(pProp);
        avgBitrate = pProp->GetValue();

        bitrAtom->FindProperty("bitr.maxBitrate",
                               (MP4Property**)&pProp,
                               NULL);
        ASSERT(pProp);
        maxBitrate = pProp->GetValue();

        if (!maxBitrate && !avgBitrate) {
            DeleteChildAtom(bitrAtom);
        }
    }

    MP4Atom::Write();
}
Example #2
0
void MP4Track::UpdateSyncSamples(MP4SampleId sampleId, bool isSyncSample)
{
	if (isSyncSample) {
		// if stss atom exists, add entry
		if (m_pStssCountProperty) {
			m_pStssSampleProperty->AddValue(sampleId);
			m_pStssCountProperty->IncrementValue();
		} // else nothing to do (yet)

	} else { // !isSyncSample
		// if stss atom doesn't exist, create one
		if (m_pStssCountProperty == NULL) {

			MP4Atom* pStssAtom = AddAtom("trak.mdia.minf.stbl", "stss");

			pStssAtom->FindProperty(
				"stss.entryCount",
				(MP4Property**)&m_pStssCountProperty);

			pStssAtom->FindProperty(
				"stss.entries.sampleNumber",
				(MP4Property**)&m_pStssSampleProperty);

			// set values for all samples that came before this one
			for (MP4SampleId sid = 1; sid < sampleId; sid++) {
				m_pStssSampleProperty->AddValue(sid);
				m_pStssCountProperty->IncrementValue();
			}
		} // else nothing to do
	}
}
Example #3
0
void MP4Track::UpdateRenderingOffsets(MP4SampleId sampleId, 
	MP4Duration renderingOffset)
{
	// if ctts atom doesn't exist
	if (m_pCttsCountProperty == NULL) {

		// no rendering offset, so nothing to do
		if (renderingOffset == 0) {
			return;
		}

		// else create a ctts atom
		MP4Atom* pCttsAtom = AddAtom("trak.mdia.minf.stbl", "ctts");

		// and get handles on the properties
		pCttsAtom->FindProperty(
			"ctts.entryCount",
			(MP4Property**)&m_pCttsCountProperty);

		pCttsAtom->FindProperty(
			"ctts.entries.sampleCount",
			(MP4Property**)&m_pCttsSampleCountProperty);

		pCttsAtom->FindProperty(
			"ctts.entries.sampleOffset",
			(MP4Property**)&m_pCttsSampleOffsetProperty);

		// if this is not the first sample
		if (sampleId > 1) {
			// add a ctts entry for all previous samples
			// with rendering offset equal to zero
			m_pCttsSampleCountProperty->AddValue(sampleId - 1);
			m_pCttsSampleOffsetProperty->AddValue(0);
			m_pCttsCountProperty->IncrementValue();;
		}
	}

	// ctts atom exists (now)

	u_int32_t numCtts = m_pCttsCountProperty->GetValue();

	// if renderingOffset == renderingOffset of last entry
	if (numCtts && renderingOffset
	   == m_pCttsSampleOffsetProperty->GetValue(numCtts-1)) {

		// increment last entry sampleCount
		m_pCttsSampleCountProperty->IncrementValue(1, numCtts-1);

	} else {
		// add ctts entry, sampleCount = 1, sampleOffset = renderingOffset
		m_pCttsSampleCountProperty->AddValue(1);
		m_pCttsSampleOffsetProperty->AddValue(renderingOffset);
		m_pCttsCountProperty->IncrementValue();
	}
}
Example #4
0
bool MP4Track::InitEditListProperties()
{
	m_pElstCountProperty = NULL;
	m_pElstMediaTimeProperty = NULL;
	m_pElstDurationProperty = NULL;
	m_pElstRateProperty = NULL;
	m_pElstReservedProperty = NULL;

	MP4Atom* pElstAtom =
		m_pTrakAtom->FindAtom("trak.edts.elst");

	if (!pElstAtom) {
		return false;
	}

	pElstAtom->FindProperty(
		"elst.entryCount",
		(MP4Property**)&m_pElstCountProperty);

	pElstAtom->FindProperty(
		"elst.entries.mediaTime",
		(MP4Property**)&m_pElstMediaTimeProperty);

	pElstAtom->FindProperty(
		"elst.entries.segmentDuration",
		(MP4Property**)&m_pElstDurationProperty);

	pElstAtom->FindProperty(
		"elst.entries.mediaRate",
		(MP4Property**)&m_pElstRateProperty);

	pElstAtom->FindProperty(
		"elst.entries.reserved",
		(MP4Property**)&m_pElstReservedProperty);

	return m_pElstCountProperty
		&& m_pElstMediaTimeProperty
		&& m_pElstDurationProperty
		&& m_pElstRateProperty
		&& m_pElstReservedProperty;
}
bool
PictureAspectRatioBox::set( MP4FileHandle file, uint16_t trackIndex, const Item& item )
{
    MP4Atom* coding;
    if( findCoding( file, trackIndex, coding ))
        throw new MP4Exception( "supported coding not found" );

    MP4Atom* pasp;
    if( findPictureAspectRatioBox( file, *coding, pasp ))
        throw new MP4Exception( "pasp-box not found" );

    MP4Integer16Property* hSpacing;
    MP4Integer16Property* vSpacing;

    if( pasp->FindProperty( "pasp.hSpacing", (MP4Property**)&hSpacing ))
        hSpacing->SetValue( item.hSpacing );

    if( pasp->FindProperty( "pasp.vSpacing", (MP4Property**)&vSpacing ))
        vSpacing->SetValue( item.vSpacing );

    return false;
}
Example #6
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);
    }

}
Example #7
0
FILE* MP4Track::GetSampleFile(MP4SampleId sampleId)
{
	u_int32_t stscIndex =
		GetSampleStscIndex(sampleId);

	u_int32_t stsdIndex = 
		m_pStscSampleDescrIndexProperty->GetValue(stscIndex);

	// check if the answer will be the same as last time
	if (m_lastStsdIndex && stsdIndex == m_lastStsdIndex) {
		return m_lastSampleFile;
	}

	MP4Atom* pStsdAtom = 
		m_pTrakAtom->FindAtom("trak.mdia.minf.stbl.stsd");
	ASSERT(pStsdAtom);

	MP4Atom* pStsdEntryAtom = 
		pStsdAtom->GetChildAtom(stsdIndex - 1);
	ASSERT(pStsdEntryAtom);

	MP4Integer16Property* pDrefIndexProperty = NULL;
	pStsdEntryAtom->FindProperty(
		"*.dataReferenceIndex",
		(MP4Property**)&pDrefIndexProperty);
	
	if (pDrefIndexProperty == NULL) {
		throw new MP4Error("invalid stsd entry", "GetSampleFile");
	}

	u_int32_t drefIndex =
		pDrefIndexProperty->GetValue();

	MP4Atom* pDrefAtom =
		m_pTrakAtom->FindAtom("trak.mdia.minf.dinf.dref");
	ASSERT(pDrefAtom);

	MP4Atom* pUrlAtom =
		pDrefAtom->GetChildAtom(drefIndex - 1);
	ASSERT(pUrlAtom);

	FILE* pFile;

	if (pUrlAtom->GetFlags() & 1) {
		pFile = NULL;	// self-contained
	} else {
#ifndef USE_FILE_CALLBACKS
		MP4StringProperty* pLocationProperty = NULL;
		pUrlAtom->FindProperty(
			"*.location", 
			(MP4Property**)&pLocationProperty);
		ASSERT(pLocationProperty);

		const char* url = pLocationProperty->GetValue();

		VERBOSE_READ_SAMPLE(m_pFile->GetVerbosity(),
			printf("dref url = %s\n", url));

		pFile = (FILE*)-1;

		// attempt to open url if it's a file url 
		// currently this is the only thing we understand
		if (!strncmp(url, "file:", 5)) {
			const char* fileName = url + 5;
			if (!strncmp(fileName, "//", 2)) {
				fileName = strchr(fileName + 2, '/');
			}
			if (fileName) {
				pFile = fopen(fileName, "rb");
				if (!pFile) {
					pFile = (FILE*)-1;
				}
			}
		} 
#else
        throw new MP4Error(errno, "Function not supported when using callbacks", "GetSampleFile");
#endif
	}

	if (m_lastSampleFile) {
#ifndef USE_FILE_CALLBACKS
		fclose(m_lastSampleFile);
#else
        throw new MP4Error(errno, "Function not supported when using callbacks", "GetSampleFile");
#endif
	}

	// cache the answer
	m_lastStsdIndex = stsdIndex;
	m_lastSampleFile = pFile;

	return pFile;
}