- Timestamp:
- Mar 5, 2009 6:02:28 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/types.h
r2471 r2489 325 325 } 326 326 327 /** 328 * Types of media frame. 329 */ 330 typedef enum pjmedia_frame_type 331 { 332 PJMEDIA_FRAME_TYPE_NONE, /**< No frame. */ 333 PJMEDIA_FRAME_TYPE_AUDIO, /**< Normal audio frame. */ 334 PJMEDIA_FRAME_TYPE_EXTENDED /**< Extended audio frame. */ 335 336 } pjmedia_frame_type; 337 338 339 /** 340 * This structure describes a media frame. 341 */ 342 typedef struct pjmedia_frame 343 { 344 pjmedia_frame_type type; /**< Frame type. */ 345 void *buf; /**< Pointer to buffer. */ 346 pj_size_t size; /**< Frame size in bytes. */ 347 pj_timestamp timestamp; /**< Frame timestamp. */ 348 pj_uint32_t bit_info; /**< Bit info of the frame, sample case: 349 a frame may not exactly start and end 350 at the octet boundary, so this field 351 may be used for specifying start & 352 end bit offset. */ 353 } pjmedia_frame; 354 355 356 /** 357 * The pjmedia_frame_ext is used to carry a more complex audio frames than 358 * the typical PCM audio frames, and it is signaled by setting the "type" 359 * field of a pjmedia_frame to PJMEDIA_FRAME_TYPE_EXTENDED. With this set, 360 * application may typecast pjmedia_frame to pjmedia_frame_ext. 361 * 362 * This structure may contain more than one audio frames, which subsequently 363 * will be called subframes in this structure. The subframes section 364 * immediately follows the end of this structure, and each subframe is 365 * represented by pjmedia_frame_ext_subframe structure. Every next 366 * subframe immediately follows the previous subframe, and all subframes 367 * are byte-aligned although its payload may not be byte-aligned. 368 */ 369 370 #pragma pack(1) 371 typedef struct pjmedia_frame_ext { 372 pjmedia_frame base; /**< Base frame info */ 373 pj_uint16_t samples_cnt; /**< Number of samples in this frame */ 374 pj_uint16_t subframe_cnt; /**< Number of (sub)frames in this frame */ 375 376 /* Zero or more (sub)frames follows immediately after this, 377 * each will be represented by pjmedia_frame_ext_subframe 378 */ 379 } pjmedia_frame_ext; 380 #pragma pack() 381 382 /** 383 * This structure represents the individual subframes in the 384 * pjmedia_frame_ext structure. 385 */ 386 #pragma pack(1) 387 typedef struct pjmedia_frame_ext_subframe { 388 pj_uint16_t bitlen; /**< Number of bits in the data */ 389 pj_uint8_t data[1]; /**< Start of encoded data */ 390 } pjmedia_frame_ext_subframe; 391 392 #pragma pack() 393 394 395 /** 396 * Append one subframe to #pjmedia_frame_ext. 397 * 398 * @param frm The #pjmedia_frame_ext. 399 * @param src Subframe data. 400 * @param bitlen Lenght of subframe, in bits. 401 * @param samples_cnt Number of audio samples in subframe. 402 */ 403 PJ_INLINE(void) pjmedia_frame_ext_append_subframe(pjmedia_frame_ext *frm, 404 const void *src, 405 unsigned bitlen, 406 unsigned samples_cnt) 407 { 408 pjmedia_frame_ext_subframe *fsub; 409 pj_uint8_t *p; 410 unsigned i; 411 412 p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext); 413 for (i = 0; i < frm->subframe_cnt; ++i) { 414 fsub = (pjmedia_frame_ext_subframe*) p; 415 p += sizeof(fsub->bitlen) + ((fsub->bitlen+7) >> 3); 416 } 417 418 fsub = (pjmedia_frame_ext_subframe*) p; 419 fsub->bitlen = (pj_uint16_t)bitlen; 420 if (bitlen) 421 pj_memcpy(fsub->data, src, (bitlen+7) >> 3); 422 423 frm->subframe_cnt++; 424 frm->samples_cnt = (pj_uint16_t)(frm->samples_cnt + samples_cnt); 425 } 426 427 /** 428 * Get a subframe from #pjmedia_frame_ext. 429 * 430 * @param frm The #pjmedia_frame_ext. 431 * @param n Subframe index, zero based. 432 * 433 * @return The n-th subframe, or NULL if n is out-of-range. 434 */ 435 PJ_INLINE(pjmedia_frame_ext_subframe*) 436 pjmedia_frame_ext_get_subframe(const pjmedia_frame_ext *frm, unsigned n) 437 { 438 pjmedia_frame_ext_subframe *sf = NULL; 439 440 if (n < frm->subframe_cnt) { 441 pj_uint8_t *p; 442 unsigned i; 443 444 p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext); 445 for (i = 0; i < n; ++i) { 446 sf = (pjmedia_frame_ext_subframe*) p; 447 p += sizeof(sf->bitlen) + ((sf->bitlen+7) >> 3); 448 } 449 450 sf = (pjmedia_frame_ext_subframe*) p; 451 } 452 453 return sf; 454 } 455 456 /** 457 * Extract all frame payload to the specified buffer. 458 * 459 * @param frm The frame. 460 * @param dst Destination buffer. 461 * @param maxsize Maximum size to copy (i.e. the size of the 462 * destination buffer). 463 * 464 * @return Total size of payload copied. 465 */ 466 PJ_INLINE(unsigned) 467 pjmedia_frame_ext_copy_payload(const pjmedia_frame_ext *frm, 468 void *dst, 469 unsigned maxlen) 470 { 471 unsigned i, copied=0; 472 for (i=0; i<frm->subframe_cnt; ++i) { 473 pjmedia_frame_ext_subframe *sf; 474 unsigned sz; 475 476 sf = pjmedia_frame_ext_get_subframe(frm, i); 477 if (!sf) 478 continue; 479 480 sz = ((sf->bitlen + 7) >> 3); 481 if (sz + copied > maxlen) 482 break; 483 484 pj_memcpy(((pj_uint8_t*)dst) + copied, sf->data, sz); 485 copied += sz; 486 } 487 return copied; 488 } 489 490 491 /** 492 * Pop out first n subframes from #pjmedia_frame_ext. 493 * 494 * @param frm The #pjmedia_frame_ext. 495 * @param n Number of first subframes to be popped out. 496 * 497 * @return PJ_SUCCESS when successful. 498 */ 499 PJ_INLINE(pj_status_t) 500 pjmedia_frame_ext_pop_subframes(pjmedia_frame_ext *frm, unsigned n) 501 { 502 pjmedia_frame_ext_subframe *sf; 503 pj_uint8_t *move_src; 504 unsigned move_len; 505 506 if (frm->subframe_cnt <= n) { 507 frm->subframe_cnt = 0; 508 frm->samples_cnt = 0; 509 return PJ_SUCCESS; 510 } 511 512 move_src = (pj_uint8_t*)pjmedia_frame_ext_get_subframe(frm, n); 513 sf = pjmedia_frame_ext_get_subframe(frm, frm->subframe_cnt-1); 514 move_len = (pj_uint8_t*)sf - move_src + sizeof(sf->bitlen) + 515 ((sf->bitlen+7) >> 3); 516 pj_memmove((pj_uint8_t*)frm+sizeof(pjmedia_frame_ext), 517 move_src, move_len); 518 519 frm->samples_cnt = (pj_uint16_t) 520 (frm->samples_cnt - n*frm->samples_cnt/frm->subframe_cnt); 521 frm->subframe_cnt = (pj_uint16_t) (frm->subframe_cnt - n); 522 523 return PJ_SUCCESS; 524 } 525 526 327 527 /** 328 528 * @}
Note: See TracChangeset
for help on using the changeset viewer.