ligzy / mp4v2

Automatically exported from code.google.com/p/mp4v2
Other
0 stars 0 forks source link

the file created by mp4v2 can't be dragged forword or backword,because mp4v2 adds all samples to the stss #128

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. I used the lib to mux a h264 file into a mp4 file.
2.
3.

What is the expected output? What do you see instead?
the expected output:only the key or sync sample should be added to the stss.
what i see: all samples are added to the stss

What version of the product are you using? On what operating system?
mp4v2 version: r487
operating system: Windows Server 2008R2

Please provide any additional information below.
A fix may be:
(In the src\mp4track.cpp)

void MP4Track::UpdateSyncSamples(MP4SampleId sampleId, bool isSyncSample)
{
    if (isSyncSample)
    {
        // if stss atom does not exist, create one
        if (m_pStssCountProperty == NULL)
        {
            MP4Atom* pStssAtom = 
                               AddAtom("trak.mdia.minf.stbl", "stss");

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

            ASSERT(pStssAtom->FindProperty(
                              "stss.entries.sampleNumber",
                              (MP4Property**)&m_pStssSampleProperty));
        }
        // add entry
        m_pStssSampleProperty->AddValue(sampleId);
        m_pStssCountProperty->IncrementValue();
    }
}

Original issue reported on code.google.com by wdwwh1717 on 6 Mar 2012 at 8:19

GoogleCodeExporter commented 9 years ago
So the code that's currently there doesn't necessarily add all samples to the 
stss:

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");

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

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

            // set values for all samples that came before this one
            uint32_t samples = GetNumberOfSamples();
            for (MP4SampleId sid = 1; sid < samples; sid++) {
                m_pStssSampleProperty->AddValue(sid);
                m_pStssCountProperty->IncrementValue();
            }
        } // else nothing to do
    }
}

So, two things:

1. If a track consists only of sync samples, then there should be no stss atom. 
 Your code would always create an stss atom, including for tracks that are 
entirely "sync points," such as most audio tracks.

2. The above code seems to presume the first sample given in each track is 
always a sync point.  So the first non-sync point sample (which, if there are 
any, would generally be the _second_ sample) would add an stss atom and flag 
all previous samples (in normal operation, should only be the _first_ sample) 
as sync points.  From that point on, only sync points would be added.

It isn't clear to me what you're doing in your writing application to end up 
with all your samples in the stss.  Could you post a code-snippet showing how 
you're writing files?  I checked a few files from a project I wrote that uses 
mp4v2, and my stss atoms were definitely correct.

Original comment by kid...@gmail.com on 19 Mar 2012 at 2:36

GoogleCodeExporter commented 9 years ago
Please reopen this if you still have an issue, but the code (so far as I can 
see) is correct.  See 
https://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap2/
qtff2.html - in particular, 

The sync sample atom identifies the key frames in the media. In a media that 
contains compressed data, key frames define starting points for portions of a 
temporally compressed sequence. The key frame is self-contained—that is, it 
is independent of preceding frames. Subsequent frames may depend on the key 
frame.

The sync sample atom provides a compact marking of the random access points 
within a stream. The table is arranged in strictly increasing order of sample 
number. If this table is not present, every sample is implicitly a random 
access point.

Sync sample atoms have an atom type of 'stss'. The sync sample atom contains a 
table of sample numbers. Each entry in the table identifies a sample that is a 
key frame for the media. If no sync sample atom exists, then all the samples 
are key frames.

...the last line, "if no sync sample atom exists, then all the samples are key 
frames," is what makes the code as-is correct.  The code doesn't bother adding 
an stss atom until a non-sync sample comes along.  If a non-sync sample comes 
along, that implies all previous samples _must_ be sync samples, and should be 
marked as such in the stss.

Closing, please re-open the issue if you still have a problem and I'll help you 
work through it.  Thanks.

Original comment by kid...@gmail.com on 20 May 2012 at 8:48