static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt ) { *p_handle = NULL; int b_regular = strcmp( psz_filename, "-" ); b_regular = b_regular && x264_is_regular_file_path( psz_filename ); if( b_regular ) { FILE *fh = x264_fopen( psz_filename, "wb" ); MP4_FAIL_IF_ERR( !fh, "cannot open output file `%s'.\n", psz_filename ); b_regular = x264_is_regular_file( fh ); fclose( fh ); } mp4_hnd_t *p_mp4 = calloc( 1, sizeof(mp4_hnd_t) ); MP4_FAIL_IF_ERR( !p_mp4, "failed to allocate memory for muxer information.\n" ); p_mp4->b_dts_compress = opt->use_dts_compress; p_mp4->b_use_recovery = 0; // we don't really support recovery p_mp4->b_fragments = !b_regular; p_mp4->b_stdout = !strcmp( psz_filename, "-" ); p_mp4->p_root = lsmash_open_movie( psz_filename, p_mp4->b_fragments ? LSMASH_FILE_MODE_WRITE_FRAGMENTED : LSMASH_FILE_MODE_WRITE ); MP4_FAIL_IF_ERR_EX( !p_mp4->p_root, "failed to create root.\n" ); p_mp4->summary = (lsmash_video_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_VIDEO ); MP4_FAIL_IF_ERR_EX( !p_mp4->summary, "failed to allocate memory for summary information of video.\n" ); p_mp4->summary->sample_type = ISOM_CODEC_TYPE_AVC1_VIDEO; *p_handle = p_mp4; return 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; }
static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt ) { mp4_hnd_t *p_mp4; *p_handle = NULL; int b_regular = strcmp( psz_filename, "-" ); b_regular = b_regular && x264_is_regular_file_path( psz_filename ); if( b_regular ) { FILE *fh = x264_fopen( psz_filename, "wb" ); MP4_FAIL_IF_ERR( !fh, "cannot open output file `%s'.\n", psz_filename ); b_regular = x264_is_regular_file( fh ); fclose( fh ); } p_mp4 = malloc( sizeof(mp4_hnd_t) ); MP4_FAIL_IF_ERR( !p_mp4, "failed to allocate memory for muxer information.\n" ); memset( p_mp4, 0, sizeof(mp4_hnd_t) ); p_mp4->b_dts_compress = opt->use_dts_compress; p_mp4->b_use_recovery = 0; p_mp4->b_no_pasp = 0; p_mp4->scale_method = ISOM_SCALE_METHOD_MEET; p_mp4->b_fragments = !b_regular; p_mp4->b_stdout = !strcmp( psz_filename, "-" ); char* ext = get_filename_extension( psz_filename ); if( !strcmp( ext, "mov" ) || !strcmp( ext, "qt" ) ) { p_mp4->major_brand = ISOM_BRAND_TYPE_QT; p_mp4->b_brand_qt = 1; } else if( !strcmp( ext, "3gp" ) ) { p_mp4->major_brand = ISOM_BRAND_TYPE_3GP6; p_mp4->i_brand_3gpp = 1; } else if( !strcmp( ext, "3g2" ) ) { p_mp4->major_brand = ISOM_BRAND_TYPE_3G2A; p_mp4->i_brand_3gpp = 2; } else p_mp4->major_brand = ISOM_BRAND_TYPE_MP42; p_mp4->p_root = lsmash_open_movie( psz_filename, p_mp4->b_fragments ? LSMASH_FILE_MODE_WRITE_FRAGMENTED : LSMASH_FILE_MODE_WRITE ); MP4_FAIL_IF_ERR_EX( !p_mp4->p_root, "failed to create root.\n" ); p_mp4->summary = (lsmash_video_summary_t *)lsmash_create_summary( LSMASH_SUMMARY_TYPE_VIDEO ); MP4_FAIL_IF_ERR_EX( !p_mp4->summary, "failed to allocate memory for summary information of video.\n" ); p_mp4->summary->sample_type = ISOM_CODEC_TYPE_AVC1_VIDEO; *p_handle = p_mp4; return 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; }
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; }