Mercurial > mplayer.hg
comparison libfaad2/syntax.c @ 25834:69a4d646e55d
generic functions and structures to parse and statekeep LATM streams
author | nicodvb |
---|---|
date | Sat, 26 Jan 2008 18:31:48 +0000 |
parents | ed27d1c01f93 |
children | bc425ba00960 |
comparison
equal
deleted
inserted
replaced
25833:ed27d1c01f93 | 25834:69a4d646e55d |
---|---|
2327 { | 2327 { |
2328 adts->crc_check = (uint16_t)faad_getbits(ld, 16 | 2328 adts->crc_check = (uint16_t)faad_getbits(ld, 16 |
2329 DEBUGVAR(1,134,"adts_error_check(): crc_check")); | 2329 DEBUGVAR(1,134,"adts_error_check(): crc_check")); |
2330 } | 2330 } |
2331 } | 2331 } |
2332 | |
2333 /* LATM parsing functions */ | |
2334 | |
2335 static uint32_t latm_get_value(bitfile *ld) | |
2336 { | |
2337 uint32_t l, value; | |
2338 uint8_t bytesForValue; | |
2339 | |
2340 bytesForValue = (uint8_t)faad_getbits(ld, 2); | |
2341 value = 0; | |
2342 for(l=0; l<bytesForValue; l++) | |
2343 value = (value << 8) | (uint8_t)faad_getbits(ld, 8); | |
2344 | |
2345 return value; | |
2346 } | |
2347 | |
2348 | |
2349 static uint32_t latmParsePayload(latm_header *latm, bitfile *ld) | |
2350 { | |
2351 //assuming there's only one program with a single layer and 1 subFrame, | |
2352 //allStreamsSametimeframing is set, | |
2353 uint32_t framelen; | |
2354 uint8_t tmp; | |
2355 | |
2356 //this should be the payload length field for the current configuration | |
2357 framelen = 0; | |
2358 if(latm->framelen_type==0) | |
2359 { | |
2360 do | |
2361 { | |
2362 tmp = (uint8_t)faad_getbits(ld, 8); | |
2363 framelen += tmp; | |
2364 } while(tmp==0xff); | |
2365 } | |
2366 else if(latm->framelen_type==1) | |
2367 framelen=latm->frameLength; | |
2368 | |
2369 return framelen; | |
2370 } | |
2371 | |
2372 | |
2373 static uint32_t latmAudioMuxElement(latm_header *latm, bitfile *ld) | |
2374 { | |
2375 uint32_t ascLen, asc_bits=0; | |
2376 uint32_t x1, y1, m, n, i; | |
2377 program_config pce; | |
2378 mp4AudioSpecificConfig mp4ASC; | |
2379 | |
2380 latm->useSameStreamMux = (uint8_t)faad_getbits(ld, 1); | |
2381 if(!latm->useSameStreamMux) | |
2382 { | |
2383 //parseSameStreamMuxConfig | |
2384 latm->version = (uint8_t) faad_getbits(ld, 1); | |
2385 if(latm->version) | |
2386 latm->versionA = (uint8_t) faad_getbits(ld, 1); | |
2387 if(latm->versionA) | |
2388 { | |
2389 //dunno the payload format for versionA | |
2390 fprintf(stderr, "versionA not supported\n"); | |
2391 return 0; | |
2392 } | |
2393 if(latm->version) //read taraBufferFullness | |
2394 latm_get_value(ld); | |
2395 latm->allStreamsSameTimeFraming = (uint8_t)faad_getbits(ld, 1); | |
2396 latm->numSubFrames = (uint8_t)faad_getbits(ld, 6) + 1; | |
2397 latm->numPrograms = (uint8_t)faad_getbits(ld, 4) + 1; | |
2398 latm->numLayers = faad_getbits(ld, 3) + 1; | |
2399 if(latm->numPrograms>1 || !latm->allStreamsSameTimeFraming || latm->numSubFrames>1 || latm->numLayers>1) | |
2400 { | |
2401 fprintf(stderr, "\r\nUnsupported LATM configuration: %d programs/ %d subframes, %d layers, allstreams: %d\n", | |
2402 latm->numPrograms, latm->numSubFrames, latm->numLayers, latm->allStreamsSameTimeFraming); | |
2403 return 0; | |
2404 } | |
2405 ascLen = 0; | |
2406 if(latm->version) | |
2407 ascLen = latm_get_value(ld); | |
2408 | |
2409 x1 = faad_get_processed_bits(ld); | |
2410 if(AudioSpecificConfigFromBitfile(ld, &mp4ASC, &pce, 0, 1) < 0) | |
2411 return 0; | |
2412 | |
2413 //horrid hack to unread the ASC bits and store them in latm->ASC | |
2414 //the correct code would rely on an ideal faad_ungetbits() | |
2415 y1 = faad_get_processed_bits(ld); | |
2416 if((y1-x1) <= MAX_ASC_BYTES*8) | |
2417 { | |
2418 faad_rewindbits(ld); | |
2419 m = x1; | |
2420 while(m>0) | |
2421 { | |
2422 n = min(m, 32); | |
2423 faad_getbits(ld, n); | |
2424 m -= n; | |
2425 } | |
2426 | |
2427 i = 0; | |
2428 m = latm->ASCbits = y1 - x1; | |
2429 while(m > 0) | |
2430 { | |
2431 n = min(m, 8); | |
2432 latm->ASC[i++] = (uint8_t) faad_getbits(ld, n); | |
2433 m -= n; | |
2434 } | |
2435 } | |
2436 | |
2437 asc_bits = y1-x1; | |
2438 | |
2439 if(ascLen>asc_bits) | |
2440 faad_getbits(ld, ascLen-asc_bits); | |
2441 | |
2442 latm->framelen_type = (uint8_t) faad_getbits(ld, 3); | |
2443 if(latm->framelen_type == 0) | |
2444 { | |
2445 latm->frameLength = 0; | |
2446 faad_getbits(ld, 8); //buffer fullness for frame_len_type==0, useless | |
2447 } | |
2448 else if(latm->framelen_type == 1) | |
2449 { | |
2450 latm->frameLength = faad_getbits(ld, 9); | |
2451 if(latm->frameLength==0) | |
2452 { | |
2453 fprintf(stderr, "Invalid frameLength: 0\r\n"); | |
2454 return 0; | |
2455 } | |
2456 latm->frameLength = (latm->frameLength+20)*8; | |
2457 } | |
2458 else | |
2459 { //hellish CELP or HCVX stuff, discard | |
2460 fprintf(stderr, "Unsupported CELP/HCVX framelentype: %d\n", latm->framelen_type); | |
2461 return 0; | |
2462 } | |
2463 | |
2464 latm->otherDataLenBits = 0; | |
2465 if(faad_getbits(ld, 1)) | |
2466 { //other data present | |
2467 int esc, tmp; | |
2468 if(latm->version) | |
2469 latm->otherDataLenBits = latm_get_value(ld); | |
2470 else do | |
2471 { | |
2472 esc = faad_getbits(ld, 1); | |
2473 tmp = faad_getbits(ld, 8); | |
2474 latm->otherDataLenBits = (latm->otherDataLenBits << 8) + tmp; | |
2475 } while(esc); | |
2476 } | |
2477 if(faad_getbits(ld, 1)) //crc | |
2478 faad_getbits(ld, 8); | |
2479 latm->inited = 1; | |
2480 } | |
2481 | |
2482 //read payload | |
2483 if(latm->inited) | |
2484 return latmParsePayload(latm, ld); | |
2485 else | |
2486 return 0; | |
2487 } | |
2488 | |
2489 | |
2490 uint32_t faad_latm_frame(latm_header *latm, bitfile *ld) | |
2491 { | |
2492 uint16_t len; | |
2493 uint32_t initpos, endpos, firstpos, ret; | |
2494 | |
2495 firstpos = faad_get_processed_bits(ld); | |
2496 while(!ld->error && !ld->no_more_reading) | |
2497 { | |
2498 faad_byte_align(ld); | |
2499 if(faad_showbits(ld, 11) != 0x2B7) | |
2500 { | |
2501 faad_getbits(ld, 8); | |
2502 continue; | |
2503 } | |
2504 faad_getbits(ld, 11); | |
2505 len = faad_getbits(ld, 13); | |
2506 if(!len) | |
2507 continue; | |
2508 initpos = faad_get_processed_bits(ld); | |
2509 ret = latmAudioMuxElement(latm, ld); | |
2510 endpos = faad_get_processed_bits(ld); | |
2511 if(ret>0) | |
2512 return (len*8)-(endpos-initpos); | |
2513 //faad_getbits(ld, initpos-endpos); //go back to initpos, but is valid a getbits(-N) ? | |
2514 } | |
2515 return -1U; | |
2516 } |