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 }