static int vc1_importer_probe( importer_t *importer ) { /* Find the first start code. */ vc1_importer_t *vc1_imp = create_vc1_importer( importer ); if( !vc1_imp ) return LSMASH_ERR_MEMORY_ALLOC; lsmash_bs_t *bs = importer->bs; uint64_t first_ebdu_head_pos = 0; int err; while( 1 ) { /* The first EBDU in decoding order of the stream shall have start code (0x000001). */ if( 0x000001 == lsmash_bs_show_be24( bs, first_ebdu_head_pos ) ) break; /* Invalid if encountered any value of non-zero before the first start code. */ if( lsmash_bs_show_byte( bs, first_ebdu_head_pos ) ) { err = LSMASH_ERR_INVALID_DATA; goto fail; } ++first_ebdu_head_pos; } /* OK. It seems the stream has a sequence header of VC-1. */ importer->info = vc1_imp; vc1_info_t *info = &vc1_imp->info; lsmash_bs_read_seek( bs, first_ebdu_head_pos, SEEK_SET ); info->ebdu_head_pos = first_ebdu_head_pos; if( (err = vc1_analyze_whole_stream( importer )) < 0 ) goto fail; lsmash_video_summary_t *summary = vc1_create_summary( info, &vc1_imp->first_sequence, vc1_imp->max_au_length ); if( !summary ) { err = LSMASH_ERR_NAMELESS; goto fail; } if( lsmash_add_entry( importer->summaries, summary ) < 0 ) { lsmash_cleanup_summary( (lsmash_summary_t *)summary ); err = LSMASH_ERR_MEMORY_ALLOC; goto fail; } /* Go back to layer of the first EBDU. */ importer->status = IMPORTER_OK; lsmash_bs_read_seek( bs, first_ebdu_head_pos, SEEK_SET ); info->prev_bdu_type = 0xFF; /* 0xFF is a forbidden value. */ info->ebdu_head_pos = first_ebdu_head_pos; uint8_t *temp_access_unit = info->access_unit.data; uint8_t *temp_incomplete_access_unit = info->access_unit.incomplete_data; memset( &info->access_unit, 0, sizeof(vc1_access_unit_t) ); info->access_unit.data = temp_access_unit; info->access_unit.incomplete_data = temp_incomplete_access_unit; memset( &info->picture, 0, sizeof(vc1_picture_info_t) ); return 0; fail: remove_vc1_importer( vc1_imp ); importer->info = NULL; lsmash_remove_entries( importer->summaries, lsmash_cleanup_summary ); return err; }
static vc1_importer_t *create_vc1_importer( importer_t *importer ) { vc1_importer_t *vc1_imp = lsmash_malloc_zero( sizeof(vc1_importer_t) ); if( !vc1_imp ) return NULL; if( vc1_setup_parser( &vc1_imp->info, 0 ) < 0 ) { remove_vc1_importer( vc1_imp ); return NULL; } return vc1_imp; }
static vc1_importer_t *create_vc1_importer( importer_t *importer ) { vc1_importer_t *vc1_imp = lsmash_malloc_zero( sizeof(vc1_importer_t) ); if( !vc1_imp ) return NULL; if( vc1_setup_parser( &vc1_imp->info, 0 ) < 0 ) { remove_vc1_importer( vc1_imp ); return NULL; } lsmash_bs_t *bs = lsmash_bs_create(); if( !bs ) { remove_vc1_importer( vc1_imp ); return NULL; } bs->stream = importer->stream; bs->read = lsmash_fread_wrapper; bs->seek = lsmash_fseek_wrapper; bs->unseekable = importer->is_stdin; bs->buffer.max_size = BS_MAX_DEFAULT_READ_SIZE; vc1_imp->bs = bs; return vc1_imp; }
static void vc1_importer_cleanup( importer_t *importer ) { debug_if( importer && importer->info ) remove_vc1_importer( importer->info ); }