Esempio n. 1
0
static lsmash_video_summary_t *vc1_create_summary( vc1_info_t *info, vc1_sequence_header_t *sequence, uint32_t max_au_length )
{
    if( !info->sequence.present || !info->entry_point.present )
        return NULL;
    lsmash_video_summary_t *summary = (lsmash_video_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_VIDEO );
    if( !summary )
        return NULL;
    lsmash_codec_specific_t *specific = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_VIDEO_VC_1,
                                                                           LSMASH_CODEC_SPECIFIC_FORMAT_UNSTRUCTURED );
    specific->data.unstructured = lsmash_create_vc1_specific_info( &info->dvc1_param, &specific->size );
    if( !specific->data.unstructured
     || lsmash_add_entry( &summary->opaque->list, specific ) < 0 )
    {
        lsmash_cleanup_summary( (lsmash_summary_t *)summary );
        lsmash_destroy_codec_specific_data( specific );
        return NULL;
    }
    summary->sample_type           = ISOM_CODEC_TYPE_VC_1_VIDEO;
    summary->max_au_length         = max_au_length;
    summary->timescale             = sequence->framerate_numerator;
    summary->timebase              = sequence->framerate_denominator;
    summary->vfr                   = !sequence->framerate_flag;
    summary->sample_per_field      = 0;
    summary->width                 = sequence->disp_horiz_size;
    summary->height                = sequence->disp_vert_size;
    summary->par_h                 = sequence->aspect_width;
    summary->par_v                 = sequence->aspect_height;
    summary->color.primaries_index = sequence->color_prim;
    summary->color.transfer_index  = sequence->transfer_char;
    summary->color.matrix_index    = sequence->matrix_coef;
    return summary;
}
Esempio n. 2
0
int lsmash_add_codec_specific_data( lsmash_summary_t *summary, lsmash_codec_specific_t *specific )
{
    if( !summary || !summary->opaque || !specific )
        return LSMASH_ERR_FUNCTION_PARAM;
    lsmash_codec_specific_t *dup = isom_duplicate_codec_specific_data( specific );
    if( !dup )
        return LSMASH_ERR_NAMELESS;
    if( lsmash_add_entry( &summary->opaque->list, dup ) < 0 )
    {
        lsmash_destroy_codec_specific_data( dup );
        return LSMASH_ERR_MEMORY_ALLOC;
    }
    return 0;
}
Esempio n. 3
0
void lsmash_cleanup_summary( lsmash_summary_t *summary )
{
    if( !summary )
        return;
    if( summary->opaque )
    {
        for( lsmash_entry_t *entry = summary->opaque->list.head; entry; )
        {
            lsmash_entry_t *next = entry->next;
            lsmash_destroy_codec_specific_data( (lsmash_codec_specific_t *)entry->data );
            lsmash_free( entry );
            entry = next;
        }
        lsmash_free( summary->opaque );
    }
    lsmash_free( summary );
}
Esempio n. 4
0
/* create AudioSpecificConfig as memory block from summary, and set it into that summary itself */
int lsmash_setup_AudioSpecificConfig( lsmash_audio_summary_t *summary )
{
    if( !summary || !summary->opaque )
        return LSMASH_ERR_FUNCTION_PARAM;
    /* Remove an old one. */
    for( lsmash_entry_t *entry = summary->opaque->list.head; entry; entry = entry->next )
    {
        lsmash_codec_specific_t *cs = (lsmash_codec_specific_t *)entry->data;
        if( !cs || cs->type != LSMASH_CODEC_SPECIFIC_DATA_TYPE_MP4SYS_DECODER_CONFIG )
            continue;
        lsmash_remove_entry_direct( &summary->opaque->list, entry, lsmash_destroy_codec_specific_data );
    }
    /* Create and add a new one. */
    uint32_t data_length;
    uint8_t *data = mp4a_export_AudioSpecificConfig( summary->aot,
                                                     summary->frequency,
                                                     summary->channels,
                                                     summary->sbr_mode,
                                                     NULL,  /* FIXME */
                                                     0,     /* FIXME */
                                                     &data_length );
    if( !data )
        return LSMASH_ERR_NAMELESS;
    lsmash_codec_specific_t *cs = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_MP4SYS_DECODER_CONFIG,
                                                                     LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED );
    if( !cs )
    {
        lsmash_free( data );
        return LSMASH_ERR_MEMORY_ALLOC;
    }
    lsmash_mp4sys_decoder_parameters_t *param = (lsmash_mp4sys_decoder_parameters_t *)cs->data.structured;
    param->objectTypeIndication = MP4SYS_OBJECT_TYPE_Audio_ISO_14496_3;
    param->streamType           = MP4SYS_STREAM_TYPE_AudioStream;
    int err = lsmash_set_mp4sys_decoder_specific_info( param, data, data_length );
    lsmash_free( data );
    if( err < 0 || (err = lsmash_add_entry( &summary->opaque->list, cs )) < 0 )
    {
        lsmash_destroy_codec_specific_data( cs );
        return err;
    }
    return 0;
}
Esempio n. 5
0
static int write_headers( hnd_t handle, x264_nal_t *p_nal )
{
    mp4_hnd_t *p_mp4 = handle;

    uint32_t sps_size = p_nal[0].i_payload - H264_NALU_LENGTH_SIZE;
    uint32_t pps_size = p_nal[1].i_payload - H264_NALU_LENGTH_SIZE;
    uint32_t sei_size = p_nal[2].i_payload;

    uint8_t *sps = p_nal[0].p_payload + H264_NALU_LENGTH_SIZE;
    uint8_t *pps = p_nal[1].p_payload + H264_NALU_LENGTH_SIZE;
    uint8_t *sei = p_nal[2].p_payload;

    lsmash_codec_specific_t *cs = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_VIDEO_H264,
                                                                     LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED );

    lsmash_h264_specific_parameters_t *param = (lsmash_h264_specific_parameters_t *)cs->data.structured;
    param->lengthSizeMinusOne = H264_NALU_LENGTH_SIZE - 1;

    /* SPS
     * The remaining parameters are automatically set by SPS. */
    if( lsmash_append_h264_parameter_set( param, H264_PARAMETER_SET_TYPE_SPS, sps, sps_size ) )
    {
        MP4_LOG_ERROR( "failed to append SPS.\n" );
        return -1;
    }

    /* PPS */
    if( lsmash_append_h264_parameter_set( param, H264_PARAMETER_SET_TYPE_PPS, pps, pps_size ) )
    {
        MP4_LOG_ERROR( "failed to append PPS.\n" );
        return -1;
    }

    if( lsmash_add_codec_specific_data( (lsmash_summary_t *)p_mp4->summary, cs ) )
    {
        MP4_LOG_ERROR( "failed to add H.264 specific info.\n" );
        return -1;
    }

    lsmash_destroy_codec_specific_data( cs );

    /* Additional extensions */
    /* Bitrate info */
    cs = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_VIDEO_H264_BITRATE,
                                            LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED );
    if( cs )
        lsmash_add_codec_specific_data( (lsmash_summary_t *)p_mp4->summary, cs );
    lsmash_destroy_codec_specific_data( cs );

    p_mp4->i_sample_entry = lsmash_add_sample_entry( p_mp4->p_root, p_mp4->i_track, p_mp4->summary );
    MP4_FAIL_IF_ERR( !p_mp4->i_sample_entry,
                     "failed to add sample entry for video.\n" );

    /* SEI */
    p_mp4->p_sei_buffer = malloc( sei_size );
    MP4_FAIL_IF_ERR( !p_mp4->p_sei_buffer,
                     "failed to allocate sei transition buffer.\n" );
    memcpy( p_mp4->p_sei_buffer, sei, sei_size );
    p_mp4->i_sei_size = sei_size;

    return sei_size + sps_size + pps_size;
}
Esempio n. 6
0
static lsmash_audio_summary_t *wave_create_summary( waveformat_extensible_t *fmt )
{
    lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO );
    if( !summary )
        return NULL;
    waveformat_extended_t *wfx = &fmt->wfx;
    summary->sample_type      = QT_CODEC_TYPE_LPCM_AUDIO;
    summary->aot              = MP4A_AUDIO_OBJECT_TYPE_NULL;
    summary->frequency        = wfx->nSamplesPerSec;
    summary->channels         = wfx->nChannels;
    summary->sample_size      = wfx->wFormatTag == WAVE_FORMAT_TYPE_ID_EXTENSIBLE
                              ? fmt->Samples.wValidBitsPerSample
                              : wfx->wBitsPerSample;
    summary->samples_in_frame = 1000;   /* arbitrary */
    summary->sbr_mode         = MP4A_AAC_SBR_NOT_SPECIFIED;
    summary->bytes_per_frame  = wfx->nBlockAlign * summary->samples_in_frame;
    summary->max_au_length    = summary->bytes_per_frame;
    lsmash_codec_specific_t *cs = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_QT_AUDIO_FORMAT_SPECIFIC_FLAGS,
                                                                     LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED );
    if( !cs )
        goto fail;
    lsmash_qt_audio_format_specific_flags_t *lpcm = (lsmash_qt_audio_format_specific_flags_t *)cs->data.structured;
    if( (summary->sample_size & 7) == 0 )
        lpcm->format_flags |= QT_AUDIO_FORMAT_FLAG_PACKED;
    else
        lpcm->format_flags |= QT_AUDIO_FORMAT_FLAG_ALIGNED_HIGH;
    if( summary->sample_size > 8 )
        lpcm->format_flags |= QT_AUDIO_FORMAT_FLAG_SIGNED_INTEGER;
    if( lsmash_add_entry( &summary->opaque->list, cs ) < 0 )
    {
        lsmash_destroy_codec_specific_data( cs );
        goto fail;
    }
    if( wfx->wFormatTag == WAVE_FORMAT_TYPE_ID_EXTENSIBLE || wfx->nChannels > 2 )
    {
        cs = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_QT_AUDIO_CHANNEL_LAYOUT,
                                                LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED );
        if( !cs )
            goto fail;
        lsmash_qt_audio_channel_layout_t *layout = (lsmash_qt_audio_channel_layout_t *)cs->data.structured;
        if( wfx->wFormatTag == WAVE_FORMAT_TYPE_ID_EXTENSIBLE )
        {
            layout->channelLayoutTag = QT_CHANNEL_LAYOUT_USE_CHANNEL_BITMAP;
            layout->channelBitmap    = fmt->dwChannelMask;
        }
        else
        {
            layout->channelLayoutTag = QT_CHANNEL_LAYOUT_UNKNOWN | wfx->nChannels;
            layout->channelBitmap    = 0;
        }
        if( lsmash_add_entry( &summary->opaque->list, cs ) < 0 )
        {
            lsmash_destroy_codec_specific_data( cs );
            goto fail;
        }
    }
    return summary;
fail:
    lsmash_cleanup_summary( (lsmash_summary_t *)summary );
    return NULL;
}
Esempio n. 7
0
static lsmash_audio_summary_t *dts_create_summary( dts_info_t *info )
{
    lsmash_audio_summary_t *summary = (lsmash_audio_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_AUDIO );
    if( !summary )
        return NULL;
    lsmash_dts_specific_parameters_t *param = &info->ddts_param;
    lsmash_codec_specific_t *specific = lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_DTS,
                                                                           LSMASH_CODEC_SPECIFIC_FORMAT_UNSTRUCTURED );
    specific->data.unstructured = lsmash_create_dts_specific_info( param, &specific->size );
    if( !specific->data.unstructured
     || lsmash_add_entry( &summary->opaque->list, specific ) < 0 )
    {
        lsmash_cleanup_summary( (lsmash_summary_t *)summary );
        lsmash_destroy_codec_specific_data( specific );
        return NULL;
    }
    /* The CODEC identifiers probably should not be the combination of 'mp4a' and
     * the objectTypeIndications for DTS audio since there is no public specification
     * which defines the encapsulation of the stream as the MPEG-4 Audio context yet.
     * In the world, there are muxers which is using such doubtful implementation.
     * The objectTypeIndications are registered at MP4RA, but this does not always
     * mean we can mux by using those objectTypeIndications.
     * If available, there shall be the specification which defines the existence of
     * DecoderSpecificInfo and its semantics, and what access unit consists of. */
    summary->sample_type = lsmash_dts_get_codingname( param );
    summary->aot         = MP4A_AUDIO_OBJECT_TYPE_NULL;     /* make no sense */
    summary->sbr_mode    = MP4A_AAC_SBR_NOT_SPECIFIED;      /* make no sense */
    switch( param->DTSSamplingFrequency )
    {
        case 12000 :    /* Invalid? (No reference in the spec) */
        case 24000 :
        case 48000 :
        case 96000 :
        case 192000 :
        case 384000 :   /* Invalid? (No reference in the spec) */
            summary->frequency = 48000;
            break;
        case 22050 :
        case 44100 :
        case 88200 :
        case 176400 :
        case 352800 :   /* Invalid? (No reference in the spec) */
            summary->frequency = 44100;
            break;
        case 8000 :     /* Invalid? (No reference in the spec) */
        case 16000 :
        case 32000 :
        case 64000 :
        case 128000 :
            summary->frequency = 32000;
            break;
        default :
            summary->frequency = 0;
            break;
    }
    summary->samples_in_frame = (summary->frequency * info->frame_duration) / param->DTSSamplingFrequency;
    summary->max_au_length    = DTS_MAX_CORE_SIZE + DTS_MAX_NUM_EXSS * DTS_MAX_EXSS_SIZE;
    summary->sample_size      = param->pcmSampleDepth;
    summary->channels         = dts_get_max_channel_count( info );
    return summary;
}