Changeset 1008
- Timestamp:
- 01/01/09 22:18:05 (1 year ago)
- Files:
-
- trunk/CommonUtils.c (modified) (2 diffs)
- trunk/CommonUtils.h (modified) (1 diff)
- trunk/FFusionCodec.c (modified) (2 diffs)
- trunk/bitstream_info.c (modified) (4 diffs)
- trunk/bitstream_info.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/CommonUtils.c
r970 r1008 295 295 }; 296 296 297 static const CFStringRef defaultForcedAppList[] = { 298 CFSTR("iChat"), 299 }; 300 297 301 static int findNameInList(CFStringRef loadingApp, const CFStringRef *names, int count) 298 302 { … … 308 312 } 309 313 314 static CFDictionaryRef getMyProcessInformation() 315 { 316 ProcessSerialNumber myProcess; 317 GetCurrentProcess(&myProcess); 318 CFDictionaryRef processInformation; 319 320 processInformation = ProcessInformationCopyDictionary(&myProcess, kProcessDictionaryIncludeAllInformationMask); 321 return processInformation; 322 } 323 324 static CFStringRef getProcessName(CFDictionaryRef processInformation) 325 { 326 CFStringRef path = CFDictionaryGetValue(processInformation, kCFBundleExecutableKey); 327 CFRange entireRange = CFRangeMake(0, CFStringGetLength(path)), basename; 328 329 CFStringFindWithOptions(path, CFSTR("/"), entireRange, kCFCompareBackwards, &basename); 330 331 basename.location += 1; //advance past "/" 332 basename.length = entireRange.length - basename.location; 333 334 CFStringRef myProcessName = CFStringCreateWithSubstring(NULL, path, basename); 335 return myProcessName; 336 } 337 338 static int isApplicationNameInList(CFStringRef prefOverride, const CFStringRef *defaultList, unsigned int defaultListCount) 339 { 340 CFDictionaryRef processInformation = getMyProcessInformation(); 341 342 if (!processInformation) 343 return FALSE; 344 345 CFArrayRef list = CFPreferencesCopyAppValue(prefOverride, CFSTR("org.perian.Perian")); 346 if(list && CFGetTypeID(list) != CFArrayGetTypeID()) 347 list = NULL; 348 349 CFStringRef myProcessName = getProcessName(processInformation); 350 int ret; 351 352 if (list) { 353 int count = CFArrayGetCount(list); 354 CFStringRef names[count]; 355 356 CFArrayGetValues(list, CFRangeMake(0, count), (void *)names); 357 ret = findNameInList(myProcessName, names, count); 358 CFRelease(list); 359 } else { 360 ret = findNameInList(myProcessName, defaultList, defaultListCount); 361 } 362 CFRelease(myProcessName); 363 CFRelease(processInformation); 364 365 return ret; 366 } 367 310 368 int IsFrameDroppingEnabled() 311 369 { 312 370 static int enabled = -1; 313 371 314 if (enabled == -1) { 315 ProcessSerialNumber myProcess; 316 GetCurrentProcess(&myProcess); 317 CFDictionaryRef processInformation; 318 319 processInformation = ProcessInformationCopyDictionary(&myProcess, kProcessDictionaryIncludeAllInformationMask); 320 321 if (!processInformation) enabled = FALSE; 322 else { 323 CFArrayRef list = CFPreferencesCopyAppValue(CFSTR("FrameDroppingWhiteList"), CFSTR("org.perian.Perian")); 324 if(list && CFGetTypeID(list) != CFArrayGetTypeID()) 325 list = NULL; 326 CFStringRef path = CFDictionaryGetValue(processInformation, kCFBundleExecutableKey); 327 CFRange entireRange = CFRangeMake(0, CFStringGetLength(path)), basename; 328 329 CFStringFindWithOptions(path, CFSTR("/"), entireRange, kCFCompareBackwards, &basename); 330 331 basename.location += 1; //advance past "/" 332 basename.length = entireRange.length - basename.location; 333 334 CFStringRef myProcessName = CFStringCreateWithSubstring(NULL, path, basename); 335 336 if (list) { 337 int count = CFArrayGetCount(list); 338 CFStringRef names[count]; 339 340 CFArrayGetValues(list, CFRangeMake(0, count), (void *)names); 341 enabled = findNameInList(myProcessName, names, count); 342 CFRelease(list); 343 } else { 344 int count = sizeof(defaultFrameDroppingWhiteList)/sizeof(defaultFrameDroppingWhiteList[0]); 345 enabled = findNameInList(myProcessName, defaultFrameDroppingWhiteList, count); 346 } 347 CFRelease(myProcessName); 348 CFRelease(processInformation); 349 } 350 } 351 372 if (enabled == -1) 373 enabled = isApplicationNameInList(CFSTR("FrameDroppingWhiteList"), 374 defaultFrameDroppingWhiteList, 375 sizeof(defaultFrameDroppingWhiteList)/sizeof(defaultFrameDroppingWhiteList[0])); 352 376 return enabled; 353 377 } 378 379 int forcePerianToDecode() 380 { 381 static int forced = -1; 382 383 if(forced == -1) 384 forced = isApplicationNameInList(CFSTR("ForcePerianAppList"), 385 defaultForcedAppList, 386 sizeof(defaultForcedAppList)/sizeof(defaultForcedAppList[0])); 387 return forced; 388 } trunk/CommonUtils.h
r887 r1008 40 40 41 41 int IsFrameDroppingEnabled(); 42 int forcePerianToDecode(); 42 43 43 44 #ifdef __cplusplus trunk/FFusionCodec.c
r1004 r1008 544 544 } 545 545 546 static inline int shouldDecode(FFusionGlobals glob, enum CodecID codecID) 547 { 548 FFusionDecodeAbilities decode = FFUSION_PREFER_DECODE; 549 if (glob->componentType == 'avc1') 550 decode = ffusionIsParsedVideoDecodable(glob->begin.parser); 551 if(decode > FFUSION_CANNOT_DECODE && 552 (codecID == CODEC_ID_H264 || codecID == CODEC_ID_MPEG4) && CFPreferencesGetAppBooleanValue(CFSTR("PreferAppleCodecs"), PERIAN_PREF_DOMAIN, NULL)) 553 decode = FFUSION_PREFER_NOT_DECODE; 554 if(decode > FFUSION_CANNOT_DECODE) 555 if(forcePerianToDecode()) 556 decode = FFUSION_PREFER_DECODE; 557 return decode > FFUSION_PREFER_NOT_DECODE; 558 } 559 546 560 //----------------------------------------------------------------- 547 561 // ImageCodecPreflight … … 813 827 ffusionLogDebugInfo(glob->begin.parser, glob->fileLog); 814 828 815 if ((glob->componentType == 'avc1' && !ffusionIsParsedVideoDecodable(glob->begin.parser)) || 816 (codecID == CODEC_ID_H264 || codecID == CODEC_ID_MPEG4) && CFPreferencesGetAppBooleanValue(CFSTR("PreferAppleCodecs"), PERIAN_PREF_DOMAIN, NULL)) 829 if (!shouldDecode(glob, codecID)) 817 830 err = featureUnsupported; 818 831 trunk/bitstream_info.c
r1002 r1008 258 258 int log2_max_frame_num; 259 259 int frame_mbs_only_flag; 260 int num_reorder_frames; 260 261 int pic_order_present_flag; 261 262 … … 337 338 } 338 339 340 static void skip_hrd_parameters(GetBitContext *gb) 341 { 342 int cpb_cnt_minus1 = get_ue_golomb(gb); 343 get_bits(gb, 4); //bit_rate_scale 344 get_bits(gb, 4); //cpb_size_scale 345 int i; 346 for(i=0; i<=cpb_cnt_minus1; i++) 347 { 348 get_ue_golomb(gb); //bit_rate_value_minus1[i] 349 get_ue_golomb(gb); //cpb_size_value_minus1[i] 350 get_bits1(gb); //cbr_flag[i] 351 } 352 get_bits(gb, 5); //initial_cpb_removal_delay_length_minus1 353 get_bits(gb, 5); //cpb_removal_delay_length_minus1 354 get_bits(gb, 5); //dpb_output_delay_length_minus1 355 get_bits(gb, 5); //time_offset_length 356 } 357 339 358 static void decode_sps(H264ParserContext *context, const uint8_t *buf, int buf_size) 340 359 { … … 381 400 get_ue_golomb(gb); //pic_width_in_mbs_minus1 382 401 get_ue_golomb(gb); //pic_height_in_map_units_minus1 383 context->frame_mbs_only_flag = get_bits1(gb); 402 int mbs_only = get_bits1(gb); 403 context->frame_mbs_only_flag = mbs_only; 404 #if 0 //This is a test to get num_reorder_frames 405 if(!mbs_only) 406 get_bits1(gb); //mb_adaptive_frame_field_flag 407 get_bits1(gb); //direct_8x8_inference_flag 408 if(get_bits1(gb)) //frame_cropping_flag 409 { 410 get_ue_golomb(gb); //frame_crop_left_offset 411 get_ue_golomb(gb); //frame_crop_right_offset 412 get_ue_golomb(gb); //frame_crop_top_offset 413 get_ue_golomb(gb); //frame_crop_bottom_offset 414 } 415 if(get_bits1(gb)) //vui_parameters_present_flag 416 { 417 if(get_bits1(gb)) //aspect_ratio_info_present_flag 418 { 419 if(get_bits(gb, 8) == 255) //aspect_ratio_idc 420 { 421 get_bits(gb, 16); //sar_width 422 get_bits(gb, 16); //sar_height 423 } 424 } 425 if(get_bits1(gb)) //overscan_info_present_flag 426 get_bits1(gb); //overscan_appropriate_flag 427 if(get_bits1(gb)) //video_signal_type_present_flag 428 { 429 get_bits(gb, 3); //video_format 430 get_bits1(gb); //video_full_range_flag 431 if(get_bits1(gb)) //colour_description_present_flag 432 { 433 get_bits(gb, 8); //colour_primaries 434 get_bits(gb, 8); //transfer_characteristics 435 get_bits(gb, 8); //matrix_coefficients 436 } 437 } 438 if(get_bits1(gb)) //chroma_loc_info_present_flag 439 { 440 get_ue_golomb(gb); //chroma_sample_loc_type_top_field 441 get_ue_golomb(gb); //chroma_sample_loc_type_bottom_field 442 } 443 if(get_bits1(gb)) //timing_info_present_flag 444 { 445 get_bits(gb, 32); //num_units_in_tick 446 get_bits(gb, 32); //time_scale 447 get_bits1(gb); //fixed_frame_rate_flag 448 } 449 int nal_hrd_parameters_present_flag = get_bits1(gb); 450 if(nal_hrd_parameters_present_flag) 451 { 452 skip_hrd_parameters(gb); 453 } 454 int vcl_hrd_parameters_present_flag = get_bits1(gb); 455 if(vcl_hrd_parameters_present_flag) 456 { 457 skip_hrd_parameters(gb); 458 } 459 if(nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) 460 get_bits1(gb); //low_delay_hrd_flag 461 get_bits1(gb); //pic_struct_present_flag 462 if(get_bits1(gb)) //bitstream_restriction_flag 463 { 464 get_bits1(gb); //motion_vectors_over_pic_boundaries_flag 465 get_ue_golomb(gb); //max_bytes_per_pic_denom 466 get_ue_golomb(gb); //max_bits_per_mb_denom 467 get_ue_golomb(gb); //log2_max_mv_length_horizontal 468 get_ue_golomb(gb); //log2_max_mv_length_vertical 469 context->num_reorder_frames = get_ue_golomb(gb); 470 get_ue_golomb(gb); //max_dec_frame_buffering 471 } 472 } 473 #endif 384 474 } 385 475 … … 879 969 } 880 970 881 intffusionIsParsedVideoDecodable(FFusionParserContext *parser)882 { 883 if (!parser) return 1;971 FFusionDecodeAbilities ffusionIsParsedVideoDecodable(FFusionParserContext *parser) 972 { 973 if (!parser) return FFUSION_PREFER_DECODE; 884 974 885 975 if (parser->parserStructure == &ffusionH264Parser) { 886 976 H264ParserContext *h264parser = parser->internalContext; 887 int no_decode = 0;977 FFusionDecodeAbilities ret = FFUSION_PREFER_DECODE; 888 978 889 979 //QT is bad at high profile 890 980 //FIXME QT is also bad at B-pyramid (sps.vui.num_reorder_frames > 1) 891 981 //but to parse that we should just use ffh264 directly 892 no_decode |= h264parser->profile_idc < 100 && !CFPreferencesGetAppBooleanValue(CFSTR("DecodeAllProfiles"), CFSTR("org.perian.Perian"), NULL); 982 if(h264parser->profile_idc < 100 && !CFPreferencesGetAppBooleanValue(CFSTR("DecodeAllProfiles"), CFSTR("org.perian.Perian"), NULL)) 983 ret = FFUSION_PREFER_NOT_DECODE; 893 984 894 985 //PAFF/MBAFF 895 986 //ffmpeg is ok at this now but we can't test it (not enough AVCHD samples) 896 987 //and the quicktime api for it may or may not actually exist 897 no_decode |= !h264parser->frame_mbs_only_flag; 988 if(!h264parser->frame_mbs_only_flag) 989 ret = FFUSION_CANNOT_DECODE; 898 990 899 991 //4:2:2 chroma 900 no_decode |= h264parser->chroma_format_idc > 1; 901 902 return !no_decode; 903 } 904 905 return 1; 992 if(h264parser->chroma_format_idc > 1) 993 ret = FFUSION_CANNOT_DECODE; 994 995 return ret; 996 } 997 998 return FFUSION_PREFER_DECODE; 906 999 } 907 1000 #ifdef DEBUG_BUILD trunk/bitstream_info.h
r989 r1008 39 39 } FFusionParser; 40 40 41 typedef enum { 42 FFUSION_CANNOT_DECODE, 43 FFUSION_PREFER_NOT_DECODE, 44 FFUSION_PREFER_DECODE, 45 } FFusionDecodeAbilities; 46 41 47 void initFFusionParsers(); 42 48 FFusionParserContext *ffusionParserInit(int codec_id); … … 44 50 int ffusionParse(FFusionParserContext *parser, const uint8_t *buf, int buf_size, int *out_buf_size, int *type, int *skippable); 45 51 void ffusionLogDebugInfo(FFusionParserContext *parser, FILE *log); 46 intffusionIsParsedVideoDecodable(FFusionParserContext *parser);52 FFusionDecodeAbilities ffusionIsParsedVideoDecodable(FFusionParserContext *parser); 47 53 48 54 #ifdef __cplusplus
