Esempio n. 1
0
/*----------------------------------------------------------------------
|   NPT_DateTime::ToString
+---------------------------------------------------------------------*/
NPT_String
NPT_DateTime::ToString(Format format, NPT_Flags flags) const
{
    NPT_String result;
    
    if (NPT_FAILED(CheckDate(*this))) return result;
    
    switch (format) {
        case FORMAT_W3C:
            AppendNumber(result, m_Year, 4);
            result += '-';
            AppendNumber(result, m_Month, 2);
            result += '-';
            AppendNumber(result, m_Day, 2);
            result += 'T';
            AppendNumber(result, m_Hours, 2);
            result += ':';
            AppendNumber(result, m_Minutes, 2);
            result += ':';
            AppendNumber(result, m_Seconds, 2);
            if (flags & FLAG_EMIT_FRACTION) {
                result += '.';
                if (flags & FLAG_EXTENDED_PRECISION) {
                    // nanoseconds precision
                    AppendNumber(result, m_NanoSeconds, 9);
                } else {
                    // only miliseconds precision
                    AppendNumber(result, m_NanoSeconds/1000000, 3);
                }
            }
            if (m_TimeZone) {
                NPT_UInt32 tz;
                if (m_TimeZone > 0) {
                    result += '+';
                    tz = m_TimeZone;
                } else {
                    result += '-';
                    tz = -m_TimeZone;
                }
                AppendNumber(result, tz/60, 2);
                result += ':';
                AppendNumber(result, tz%60, 2);
            } else {
                result += 'Z';
            }
            break;
            
        case FORMAT_ANSI: {
            // compute the number of days elapsed since 1900
            NPT_UInt32 days = ElapsedDaysSince1900(*this);
            
            // format the result
            result.SetLength(24);
            NPT_FormatString(result.UseChars(), result.GetLength()+1, 
                             "%.3s %.3s%3d %.2d:%.2d:%.2d %d",
                             NPT_TIME_DAYS_SHORT[(days+1)%7],
                             NPT_TIME_MONTHS[m_Month-1],
                             m_Day,
                             m_Hours,
                             m_Minutes,
                             m_Seconds,
                             m_Year);
            break;
        }
            
        case FORMAT_RFC_1036:
        case FORMAT_RFC_1123: {
            // compute the number of days elapsed since 1900
            NPT_UInt32 days = ElapsedDaysSince1900(*this);

            if (format == FORMAT_RFC_1036) {
                result += NPT_TIME_DAYS_LONG[(days+1)%7];
                result += ", ";
                AppendNumber(result, m_Day, 2);
                result += '-';
                result += NPT_TIME_MONTHS[m_Month-1];
                result += '-';
                AppendNumber(result, m_Year%100, 2);
            } else {
                result += NPT_TIME_DAYS_SHORT[(days+1)%7];
                result += ", ";
                AppendNumber(result, m_Day, 2);
                result += ' ';
                result += NPT_TIME_MONTHS[m_Month-1];
                result += ' ';
                AppendNumber(result, m_Year, 4);
            }
            result += ' ';
            AppendNumber(result, m_Hours, 2);
            result += ':';
            AppendNumber(result, m_Minutes, 2);
            result += ':';
            AppendNumber(result, m_Seconds, 2);
            if (m_TimeZone) {
                if (m_TimeZone > 0) {
                    result += " +";
                    AppendNumber(result, m_TimeZone/60, 2);
                    AppendNumber(result, m_TimeZone%60, 2);
                } else {
                    result += " -";
                    AppendNumber(result, -m_TimeZone/60, 2);
                    AppendNumber(result, -m_TimeZone%60, 2);
                }
            } else {
                result += " GMT";
            }
            break;
        }
    }

    return result;
}
/*----------------------------------------------------------------------
|   Mp4ParserOutput_ProcessCryptoInfo
+---------------------------------------------------------------------*/
static BLT_Result
Mp4ParserOutput_ProcessCryptoInfo(Mp4ParserOutput*        self, 
                                  AP4_SampleDescription*& sample_desc)
{
    // check if the track is encrypted
    if (sample_desc->GetType() == AP4_SampleDescription::TYPE_PROTECTED) {
        ATX_LOG_FINE("track is encrypted");
        AP4_ProtectedSampleDescription* prot_desc = dynamic_cast<AP4_ProtectedSampleDescription*>(sample_desc);
        if (prot_desc == NULL) {
            ATX_LOG_FINE("unable to obtain cipher info");
            return BLT_ERROR_INVALID_MEDIA_FORMAT;
        }

        // obtain the key manager
        if (self->parser->key_manager == NULL) {
            ATX_Properties* properties = NULL;
            if (BLT_SUCCEEDED(BLT_Core_GetProperties(ATX_BASE(self->parser, BLT_BaseMediaNode).core, 
                                                              &properties))) {
                ATX_PropertyValue value;
                if (ATX_SUCCEEDED(ATX_Properties_GetProperty(properties, 
                                                             BLT_KEY_MANAGER_PROPERTY, 
                                                             &value))) {
                    if (value.type == ATX_PROPERTY_VALUE_TYPE_POINTER) {
                        self->parser->key_manager = (BLT_KeyManager*)value.data.pointer;
                    }
                } else {
                    ATX_LOG_FINE("no key manager");
                }
            }
        }
        if (self->parser->key_manager == NULL) return BLT_ERROR_NO_MEDIA_KEY;
        
        // check if we need to use a cipher factory
        if (self->parser->cipher_factory == NULL) {
            ATX_Properties* properties = NULL;
            if (BLT_SUCCEEDED(BLT_Core_GetProperties(ATX_BASE(self->parser, BLT_BaseMediaNode).core, 
                                                              &properties))) {
                ATX_PropertyValue value;
                if (ATX_SUCCEEDED(ATX_Properties_GetProperty(properties, 
                                                             BLT_CIPHER_FACTORY_PROPERTY, 
                                                             &value))) {
                    if (value.type == ATX_PROPERTY_VALUE_TYPE_POINTER) {
                        self->parser->cipher_factory = new BLT_Ap4CipherFactoryAdapter((BLT_CipherFactory*)value.data.pointer);
                    }
                }
            }
        }
        
        // figure out the content ID for this track
        // TODO: support different content ID schemes
        // for now, we just make up a content ID based on the track ID
        char content_id[32];
        NPT_FormatString(content_id, sizeof(content_id), "@track.%d", self->track->GetId());
        
        // get the key for this content
        unsigned int   key_size = 256;
        NPT_DataBuffer key(key_size);
        BLT_Result result = BLT_KeyManager_GetKeyByName(self->parser->key_manager, content_id, key.UseData(), &key_size);
        if (result == ATX_ERROR_NOT_ENOUGH_SPACE) {
            key.SetDataSize(key_size);
            result = BLT_KeyManager_GetKeyByName(self->parser->key_manager, content_id, key.UseData(), &key_size);
        }
        if (BLT_FAILED(result)) return BLT_ERROR_NO_MEDIA_KEY;
        key.SetDataSize(key_size);
        
        delete self->sample_decrypter;
        self->sample_decrypter = AP4_SampleDecrypter::Create(prot_desc, key.GetData(), key_size, self->parser->cipher_factory);
        if (self->sample_decrypter == NULL) {
            ATX_LOG_FINE("unable to create decrypter");
            return BLT_ERROR_CRYPTO_FAILURE;
        }
        
        // switch to the original sample description
        sample_desc = prot_desc->GetOriginalSampleDescription();
    }
    
    return BLT_SUCCESS;
}