Commit a08cd05e authored by Ramesh Nallur's avatar Ramesh Nallur

Modified files to support mp4 time seek. This is the real checkin

parent 8cc42a86
......@@ -203,6 +203,7 @@ if ADD_UTIL
bin_PROGRAMS += mp4tags
bin_PROGRAMS += mp4track
bin_PROGRAMS += mp4trackdump
bin_PROGRAMS += mp4clip
endif
mp4art_SOURCES = util/impl.h util/mp4art.cpp
......@@ -214,6 +215,7 @@ mp4subtitle_SOURCES = util/impl.h util/mp4subtitle.cpp
mp4tags_SOURCES = util/impl.h util/mp4tags.cpp
mp4track_SOURCES = util/impl.h util/mp4track.cpp
mp4trackdump_SOURCES = util/impl.h util/mp4trackdump.cpp
mp4clip_SOURCES = util/impl.h util/mp4clip.cpp
mp4art_LDADD = libmp4v2.la $(X_LDFLAGS)
mp4chaps_LDADD = libmp4v2.la $(X_LDFLAGS)
......@@ -224,6 +226,7 @@ mp4subtitle_LDADD = libmp4v2.la $(X_LDFLAGS)
mp4tags_LDADD = libmp4v2.la $(X_LDFLAGS)
mp4track_LDADD = libmp4v2.la $(X_LDFLAGS)
mp4trackdump_LDADD = libmp4v2.la $(X_LDFLAGS)
mp4clip_LDADD = libmp4v2.la $(X_LDFLAGS)
###############################################################################
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2009-04-28.21; # UTC
scriptversion=2011-12-04.11; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
# Software Foundation, Inc.
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
# 2011 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -44,7 +44,7 @@ Environment variables:
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
......@@ -90,10 +90,18 @@ if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u="sed s,\\\\\\\\,/,g"
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
......@@ -158,10 +166,12 @@ gcc)
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
......@@ -405,6 +415,52 @@ tru64)
rm -f "$tmpdepfile"
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test "$stat" = 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/ \1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/ /
G
p
}' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
......@@ -503,7 +559,9 @@ makedepend)
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
......
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2009-04-28.21; # UTC
scriptversion=2011-01-19.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
......@@ -156,6 +156,10 @@ while test $# -ne 0; do
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
......@@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
fi
shift # arg
dst_arg=$arg
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
......@@ -200,7 +208,11 @@ if test $# -eq 0; then
fi
if test -z "$dir_arg"; then
trap '(exit $?); exit' 1 2 13 15
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
......@@ -228,9 +240,9 @@ fi
for src
do
# Protect names starting with `-'.
# Protect names problematic for `test' and other utilities.
case $src in
-*) src=./$src;;
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
......@@ -252,12 +264,7 @@ do
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
......@@ -385,7 +392,7 @@ do
case $dstdir in
/*) prefix='/';;
-*) prefix='./';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
......@@ -403,7 +410,7 @@ do
for d
do
test -z "$d" && continue
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
......
This diff is collapsed.
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2009-04-28.21; # UTC
scriptversion=2012-01-06.13; # UTC
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009 Free Software Foundation, Inc.
# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
......@@ -84,7 +84,6 @@ Supported PROGRAM values:
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
......@@ -122,15 +121,6 @@ case $1 in
# Not GNU programs, they don't have --version.
;;
tar*)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
......@@ -226,7 +216,7 @@ WARNING: \`$1' $msg. You should only need it if
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG="\${$#}"
eval LASTARG=\${$#}
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
......@@ -256,7 +246,7 @@ WARNING: \`$1' is $msg. You should only need it if
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG="\${$#}"
eval LASTARG=\${$#}
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
......@@ -318,41 +308,6 @@ WARNING: \`$1' is $msg. You should only need it if
touch $file
;;
tar*)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case $firstarg in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case $firstarg in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
......
This diff is collapsed.
......@@ -20,7 +20,7 @@ m4_define([PRJ_version_hex],m4_format([0x%04x%02x%02x],PRJ_version_major,PRJ_ver
m4_define([PRJ_version],ifelse(
PRJ_repo_type,[stable],m4_format([%s],PRJ_repo_branch),
m4_format([%s-r%d],PRJ_repo_branch,PRJ_repo_rev)))
m4_format([%s-r%s],PRJ_repo_branch,PRJ_repo_rev)))
###############################################################################
# initialization
......
......@@ -303,12 +303,61 @@ MP4FileHandle MP4Modify(
*
* @return <b>true</b> on success, <b>false</b> on failure.
*/
MP4V2_EXPORT
bool MP4Optimize(
const char* fileName,
const char* newFileName DEFAULT(NULL) );
/** Optimize the layout of an mp4 file.
*
* MP4Optimize reads an existing mp4 file and writes a new version of the
* file with the two important changes:
*
* First, the mp4 control information is moved to the beginning of the file.
* (Frequenty it is at the end of the file due to it being constantly
* modified as track samples are added to an mp4 file). This optimization
* is useful in that in allows the mp4 file to be HTTP streamed.
*
* Second, the track samples are interleaved so that the samples for a
* particular instant in time are colocated within the file. This
* eliminates disk seeks during playback of the file which results in
* better performance.
*
* There are also two important side effects of MP4Optimize():
*
* First, any free blocks within the mp4 file are eliminated.
*
* Second, as a side effect of the sample interleaving process any media
* data chunks that are not actually referenced by the mp4 control
* structures are deleted. This is useful if you have called MP4DeleteTrack()
* which only deletes the control information for a track, and not the
* actual media data.
*
* @param fileName pathname of (existing) file to be optimized.
* On Windows, this should be a UTF-8 encoded string.
* On other platforms, it should be an 8-bit encoding that is
* appropriate for the platform, locale, file system, etc.
* (prefer to use UTF-8 when possible).
* @param newFileName pathname of the new optimized file.
* On Windows, this should be a UTF-8 encoded string.
* On other platforms, it should be an 8-bit encoding that is
* appropriate for the platform, locale, file system, etc.
* (prefer to use UTF-8 when possible).
* If NULL a temporary file in the same directory as the
* <b>fileName</b> will be used and <b>fileName</b>
* will be over-written upon successful completion.
* @param indexFilename pathname of the new optimized file.
* On Windows, this should be a UTF-8 encoded string.
* @return <b>true</b> on success, <b>false</b> on failure.
*/
MP4V2_EXPORT
bool MP4OptimizeForTimeSeek(const char* fileName, const char* newFileName, const char* indexFileName);
/** Read an existing mp4 file.
*
* MP4Read is the first call that should be used when you want to just
......
......@@ -281,6 +281,12 @@ MP4EditId MP4AddTrackEdit(
MP4Duration duration DEFAULT(0),
bool dwell DEFAULT(false) );
MP4V2_EXPORT
MP4EditId MP4AddTrackEditDummy(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4EditId editId);
MP4V2_EXPORT
bool MP4DeleteTrackEdit(
MP4FileHandle hFile,
......
......@@ -9,9 +9,9 @@
// Thanks, MSFT, for making C99 a total PITA. Declare this not to define any stdint stuff; this is useful
// if you're going to be using mp4v2 on windows with some other library that defines its own stdint.
// TODO msft has finally re-included stdint in vs2010, so maybe at some point in the future this won't be needed.
// The 1600 version check is for Visual Studio 2010 which has stdint once again.
#ifndef MP4V2_NO_STDINT_DEFS
#if defined( _WIN32 ) && !defined( __MINGW32__ )
#if defined( _WIN32 ) && !defined( __MINGW32__ ) && !(defined(_MSC_VER) && _MSC_VER >= 1600)
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
......
......@@ -11,5 +11,5 @@ define([PRJ_url_discussion], [http://groups.google.com/group/mp4v2])
define([PRJ_irc], [irc://irc.freenode.net/handbrake])
define([PRJ_bugreport], [kidjan@gmail.com])
define([PRJ_version_major], [2])
define([PRJ_version_minor], [0])
define([PRJ_version_minor], [1])
define([PRJ_version_point], [0])
......@@ -61,6 +61,58 @@ void MP4ElstAtom::AddProperties(uint8_t version)
new MP4Integer16Property(pTable->GetParentAtom(), "reserved"));
}
uint32_t MP4ElstAtom::GetMediaTimeOffset(uint64_t matchDuration)
{
MP4IntegerProperty *pElstCountProperty;
MP4IntegerProperty *pElstDurationProperty;
MP4IntegerProperty *pElstMediaTimeProperty;
uint32_t numEdits = 0;
FindProperty("elst.entryCount",
(MP4Property**)&pElstCountProperty);
if (pElstCountProperty) {
numEdits = pElstCountProperty->GetValue();
}
FindProperty(
"elst.entries.segmentDuration",
(MP4Property**)&pElstDurationProperty);
FindProperty(
"elst.entries.mediaTime",
(MP4Property**)&pElstMediaTimeProperty);
uint32_t offset = this->GetStart() + 8 + 4 + 4; // skip over the version and num edits
for (MP4EditId eid = 1; eid <= numEdits; eid++) {
uint64_t tempDuration = pElstDurationProperty->GetValue(eid - 1);
log.verbose3f("Duration for Eid:%d %lld\n", eid, tempDuration);
if ((tempDuration == matchDuration) &&
(pElstMediaTimeProperty->GetValue(eid - 1) == 0)) {
if( GetVersion() == 1) {
offset += 8;
}
else {
offset += 4 ;
}
return offset;
}
if (GetVersion() == 1) {
offset += 20;
}
else {
offset += 12;
}
}
return (uint32_t)-1;
}
void MP4ElstAtom::Generate()
{
SetVersion(0);
......
......@@ -96,14 +96,40 @@ void MP4RootAtom::BeginOptimalWrite()
WriteAtomType("ftyp", OnlyOne);
WriteAtomType("moov", OnlyOne);
WriteAtomType("udta", Many);
#if 1 //Ramesh
MP4Atom* pMdatAtom = FindAtom("mdat[0]");
if (pMdatAtom != NULL) {
pMdatAtom->BeginWrite(m_File.Use64Bits("mdat"));
log.warningf("%s: Found Mdat under moov. Size:%lld Start:%lld\n",
__FUNCTION__, pMdatAtom->GetSize(), pMdatAtom->GetStart());
}
else {
log.warningf("%s: Mdat under moov not found\n",
__FUNCTION__);
}
#else
m_pChildAtoms[GetLastMdatIndex()]->BeginWrite(m_File.Use64Bits("mdat"));
#endif
}
void MP4RootAtom::FinishOptimalWrite()
{
// finish writing mdat
#if 1 //Ramesh
MP4Atom* pMdatAtom = FindAtom("mdat[0]");
if (pMdatAtom != NULL) {
pMdatAtom->FinishWrite(m_File.Use64Bits("mdat"));
log.warningf("%s: Found Mdat under moov. Size:%lld Start:%lld\n",
__FUNCTION__, pMdatAtom->GetSize(), pMdatAtom->GetStart());
}
else {
log.warningf("%s: Mdat under moov not found\n",
__FUNCTION__);
}
#else
m_pChildAtoms[GetLastMdatIndex()]->FinishWrite(m_File.Use64Bits("mdat"));
#endif
// find moov atom
uint32_t size = m_pChildAtoms.Size();
......@@ -127,13 +153,19 @@ void MP4RootAtom::FinishOptimalWrite()
// sanity check
uint64_t newSize = pMoovAtom->GetSize();
ASSERT(oldSize == newSize);
}
uint32_t MP4RootAtom::GetLastMdatIndex()
{
for (int32_t i = m_pChildAtoms.Size() - 1; i >= 0; i--) {
if (!strcmp("mdat", m_pChildAtoms[i]->GetType())) {
for (uint32_t i = m_pChildAtoms.Size() - 1; i >= 0; i--) {
if (!strcmp("mdat", m_pChildAtoms[i]->GetType())) {
log.verbose3f("\n %s: Found Last Mdat Type:%s index:%d\n",
__FUNCTION__, m_pChildAtoms[i]->GetType(), i);
return i;
}
}
......@@ -141,6 +173,171 @@ uint32_t MP4RootAtom::GetLastMdatIndex()
return (uint32_t)-1;
}
MP4Atom* MP4RootAtom::GetNextMdatAfterMoof(uint32_t index)
{
// Find an mdat after the moof
uint32_t moofIndex = GetMoofIndex(index);
if (moofIndex == (uint32_t)-1) {
return NULL;
}
for (uint32_t i = moofIndex; i < m_pChildAtoms.Size() ; i++) {
log.verbose3f("\n %s: Mdat following moof[%d] Type:%s index:%d\n",
__FUNCTION__, index, m_pChildAtoms[i]->GetType(), i);
if (!strcmp("mdat", m_pChildAtoms[i]->GetType())) {
return m_pChildAtoms[i];
}
}
return NULL;
}
uint32_t MP4RootAtom::GetMoofIndex(int32_t index)
{
for (uint32_t i = 0; i < m_pChildAtoms.Size() ; i++)
{
if (!strcmp("moof", m_pChildAtoms[i]->GetType())) {
if (index == 0) {
log.verbose3f("\n %s: Found moof[%d] %s index:%d\n",
__FUNCTION__, index, m_pChildAtoms[i]->GetType(), i);
return i;
}
index--;
}
}
return (uint32_t) -1;
}
MP4Atom* MP4RootAtom::WriteMoof(int32_t index, uint64_t *pOffset) {
const uint32_t moofIndex = GetMoofIndex(index);
if (moofIndex == (uint32_t)-1)
return NULL;
MP4Atom *pMoofAtom = m_pChildAtoms[moofIndex];
// Before writing a moof write a free atom
MP4Atom* pFreeAtom = MP4Atom::CreateAtom(m_File, NULL, "free");
// in existing position of the moov atom
//InsertChildAtom(pFreeAtom, moofIndex);
//DeleteChildAtom(pMoofAtom);
//AddChildAtom(pMoofAtom);
//log.verbose3f("\n %s: Writing Free Atom AT Start:%lld \n",
// __FUNCTION__, moofIndex, m_pChildAtoms[i]->GetType(), i);
// write free atom to disk
//MP4Atom* pTempMoovAtom = MP4Atom::CreateAtom( m_File, NULL, "moov" );
//pTempMoovAtom->Generate();
MP4Atom* pTempMoovAtom = FindAtom("moov");
MP4Atom* pFtypAtom = FindAtom("ftyp");
if (pFtypAtom == NULL) {
ASSERT(false);
}
int64_t pos1 = m_File.GetPosition();
//Remember the offset
*pOffset = pos1 + 8;
// First Create a dummy
pFreeAtom->SetSize(0);
pFreeAtom->Write();
pFtypAtom->Write();
for (int32_t k = 0; true; k++) {
// Zero out all the stts atoms
char propName[1024];
MP4Property* pProperty = NULL;
snprintf(propName, sizeof(propName), "%s[%d].%s", "moov.trak", k, "mdia.minf.stbl.stts.entryCount");
pProperty = NULL;
pTempMoovAtom->FindProperty(propName, &pProperty);
if (pProperty == NULL)
break;
((MP4IntegerProperty*)pProperty)->SetValue(0);
pProperty = NULL;
snprintf(propName, sizeof(propName), "%s[%d].%s", "moov.trak", k, "mdia.minf.stbl.stsd.entryCount");
pTempMoovAtom->FindProperty(propName, &pProperty);
if (pProperty == NULL)
break;
log.verbose3f("\n %s: stsd:%lld \n",
__FUNCTION__, ((MP4IntegerProperty*)pProperty)->GetValue(0));
//((MP4IntegerProperty*)pProperty)->GetValue(0);//SetValue(0);
pProperty = NULL;
snprintf(propName, sizeof(propName), "%s[%d].%s", "moov.trak", k, "mdia.minf.stbl.stsc.entryCount");
pTempMoovAtom->FindProperty(propName, &pProperty);
if (pProperty == NULL)
break;
((MP4IntegerProperty*)pProperty)->SetValue(0);
pProperty = NULL;
snprintf(propName, sizeof(propName), "%s[%d].%s", "moov.trak", k, "mdia.minf.stbl.stco.entryCount");
pTempMoovAtom->FindProperty(propName, &pProperty);
if (pProperty == NULL)
break;
((MP4IntegerProperty*)pProperty)->SetValue(0);
pProperty = NULL;
snprintf(propName, sizeof(propName), "%s[%d].%s", "moov.trak", k, "mdia.minf.stbl.stsz.sampleCount");
pTempMoovAtom->FindProperty(propName, &pProperty);
if (pProperty != NULL) {
((MP4IntegerProperty*)pProperty)->SetValue(0);
}
pProperty = NULL;
snprintf(propName, sizeof(propName), "%s[%d].%s", "moov.trak", k, "mdia.minf.stbl.stss.entryCount");
pTempMoovAtom->FindProperty(propName, &pProperty);
if (pProperty != NULL) {