179 lines
3.9 KiB
C++
179 lines
3.9 KiB
C++
|
#include "mp4common.h"
|
||
|
|
||
|
size_t utf16len(const uint16_t *str)
|
||
|
{
|
||
|
size_t size=0;
|
||
|
while (*str++) size++;
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
void utf16swap(uint16_t *str)
|
||
|
{
|
||
|
while (*str)
|
||
|
{
|
||
|
*str = htons(*str);
|
||
|
str++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool MP4File::Get3GPMetadataString(const char *atom, uint16_t **value)
|
||
|
{
|
||
|
char atomstring[60];
|
||
|
snprintf(atomstring, 60, "moov.udta.%s.metadata", atom);
|
||
|
const uint8_t *str = (const uint8_t *)this->GetStringProperty(atomstring);
|
||
|
|
||
|
if (str)
|
||
|
{
|
||
|
bool reverse=false;
|
||
|
bool utf16=false;
|
||
|
if ((str[0] == 0xFE && str[1] == 0xFF))
|
||
|
{
|
||
|
reverse=true;
|
||
|
utf16=true;
|
||
|
}
|
||
|
if ((str[0] == 0xFF && str[1] == 0xFE))
|
||
|
{
|
||
|
utf16=true;
|
||
|
}
|
||
|
|
||
|
if (utf16)
|
||
|
{
|
||
|
uint16_t *utf16 = (uint16_t *)str;
|
||
|
size_t len = utf16len(utf16);
|
||
|
*value = (uint16_t *)malloc(len*sizeof(uint16_t));
|
||
|
if (!*value)
|
||
|
return false;
|
||
|
memcpy(*value, utf16+1, len*sizeof(uint16_t));
|
||
|
|
||
|
if (reverse)
|
||
|
utf16swap(*value);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, -1, 0, 0);
|
||
|
*value = (uint16_t *)malloc(len * sizeof(uint16_t));
|
||
|
if (*value == NULL)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, -1, (LPWSTR)*value, len);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool MP4File::Set3GPMetadataString(const char *atom, const uint16_t *value)
|
||
|
{
|
||
|
char atomstring[60];
|
||
|
MP4Atom *pMetaAtom;
|
||
|
MP4StringProperty *pMetadataProperty = NULL;
|
||
|
MP4Integer16Property *unknown = NULL;
|
||
|
snprintf(atomstring, 60, "moov.udta.%s", atom);
|
||
|
|
||
|
pMetaAtom = m_pRootAtom->FindAtomMP4(atomstring);
|
||
|
|
||
|
if (!pMetaAtom)
|
||
|
{
|
||
|
(void)AddDescendantAtoms("moov", atomstring+5);
|
||
|
|
||
|
//if (!CreateMetadataAtom(atom))
|
||
|
//return false;
|
||
|
|
||
|
pMetaAtom = m_pRootAtom->FindAtomMP4(atomstring);
|
||
|
if (pMetaAtom == NULL) return false;
|
||
|
}
|
||
|
|
||
|
snprintf(atomstring, 60, "%s.language", atom);
|
||
|
ASSERT(pMetaAtom->FindProperty(atomstring,
|
||
|
(MP4Property**)&unknown));
|
||
|
ASSERT(unknown);
|
||
|
unknown->SetValue(0x15C7);
|
||
|
|
||
|
|
||
|
snprintf(atomstring, 60, "%s.metadata", atom);
|
||
|
ASSERT(pMetaAtom->FindProperty(atomstring,
|
||
|
(MP4Property**)&pMetadataProperty));
|
||
|
ASSERT(pMetadataProperty);
|
||
|
|
||
|
pMetadataProperty->SetUnicode(true);
|
||
|
size_t lenWithBOM = utf16len(value) + 1;
|
||
|
uint16_t *newVal = (uint16_t *)malloc((lenWithBOM+1) * sizeof(uint16_t));
|
||
|
newVal[0]=0xFEFF;
|
||
|
memcpy(newVal+1, value, lenWithBOM*sizeof(uint16_t));
|
||
|
pMetadataProperty->SetValue((char *)newVal, 0);
|
||
|
free(newVal);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool MP4File::Get3GPMetadataInteger(const char *atom, uint64_t *value)
|
||
|
{
|
||
|
char atomstring[60];
|
||
|
snprintf(atomstring, 60, "moov.udta.%s.metadata", atom);
|
||
|
|
||
|
MP4Property* pProperty;
|
||
|
u_int32_t index;
|
||
|
|
||
|
FindIntegerProperty(atomstring, &pProperty, &index);
|
||
|
if (pProperty)
|
||
|
{
|
||
|
*value = ((MP4IntegerProperty*)pProperty)->GetValue(index);
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool MP4File::Set3GPMetadataInteger(const char *atom, uint64_t value)
|
||
|
{
|
||
|
char atomstring[60] = {0};
|
||
|
MP4Atom *pMetaAtom;
|
||
|
MP4IntegerProperty *pMetadataProperty = NULL;
|
||
|
snprintf(atomstring, 60, "moov.udta.%s", atom);
|
||
|
|
||
|
pMetaAtom = m_pRootAtom->FindAtomMP4(atomstring);
|
||
|
|
||
|
if (!pMetaAtom)
|
||
|
{
|
||
|
(void)AddDescendantAtoms("moov", atomstring+5);
|
||
|
//if (!CreateMetadataAtom(atom))
|
||
|
//return false;
|
||
|
|
||
|
pMetaAtom = m_pRootAtom->FindAtomMP4(atomstring);
|
||
|
if (pMetaAtom == NULL) return false;
|
||
|
}
|
||
|
|
||
|
snprintf(atomstring, 60, "%s.metadata", atom);
|
||
|
ASSERT(pMetaAtom->FindProperty(atomstring,
|
||
|
(MP4Property**)&pMetadataProperty));
|
||
|
ASSERT(pMetadataProperty);
|
||
|
|
||
|
pMetadataProperty->SetValue(value, 0);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool MP4File::Delete3GPMetadataAtom(const char* name)
|
||
|
{
|
||
|
MP4Atom *pMetaAtom = NULL;
|
||
|
char s[256];
|
||
|
|
||
|
snprintf(s, 256, "moov.udta.%s", name);
|
||
|
pMetaAtom = m_pRootAtom->FindAtomMP4(s);
|
||
|
/* if it exists, delete it */
|
||
|
if (pMetaAtom)
|
||
|
{
|
||
|
MP4Atom *pParent = pMetaAtom->GetParentAtom();
|
||
|
|
||
|
pParent->DeleteChildAtom(pMetaAtom);
|
||
|
|
||
|
delete pMetaAtom;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|