MCPcopy Create free account
hub / github.com/FFmpeg/FFmpeg / decode_tilehdr

Function decode_tilehdr

libavcodec/wmaprodec.c:509–595  ·  view source on GitHub ↗

*@brief Decode how the data in the frame is split into subframes. * Every WMA frame contains the encoded data for a fixed number of * samples per channel. The data for every channel might be split * into several subframes. This function will reconstruct the list of * subframes for every channel. * * If the subframes are not evenly split, the algorithm estimates

Source from the content-addressed store, hash-verified

507 *@return 0 on success, < 0 in case of an error
508 */
509static int decode_tilehdr(WMAProDecodeCtx *s)
510{
511 uint16_t num_samples[WMAPRO_MAX_CHANNELS]; /** sum of samples for all currently known subframes of a channel */
512 uint8_t contains_subframe[WMAPRO_MAX_CHANNELS]; /** flag indicating if a channel contains the current subframe */
513 int channels_for_cur_subframe = s->num_channels; /** number of channels that contain the current subframe */
514 int fixed_channel_layout = 0; /** flag indicating that all channels use the same subframe offsets and sizes */
515 int min_channel_len = 0; /** smallest sum of samples (channels with this length will be processed first) */
516 int c;
517
518 /* Should never consume more than 3073 bits (256 iterations for the
519 * while loop when always the minimum amount of 128 samples is substracted
520 * from missing samples in the 8 channel case).
521 * 1 + BLOCK_MAX_SIZE * MAX_CHANNELS / BLOCK_MIN_SIZE * (MAX_CHANNELS + 4)
522 */
523
524 /** reset tiling information */
525 for (c = 0; c < s->num_channels; c++)
526 s->channel[c].num_subframes = 0;
527
528 memset(num_samples, 0, sizeof(num_samples));
529
530 if (s->max_num_subframes == 1 || get_bits1(&s->gb))
531 fixed_channel_layout = 1;
532
533 /** loop until the frame data is split between the subframes */
534 do {
535 int subframe_len;
536
537 /** check which channels contain the subframe */
538 for (c = 0; c < s->num_channels; c++) {
539 if (num_samples[c] == min_channel_len) {
540 if (fixed_channel_layout || channels_for_cur_subframe == 1 ||
541 (min_channel_len == s->samples_per_frame - s->min_samples_per_subframe))
542 contains_subframe[c] = 1;
543 else
544 contains_subframe[c] = get_bits1(&s->gb);
545 } else
546 contains_subframe[c] = 0;
547 }
548
549 /** get subframe length, subframe_len == 0 is not allowed */
550 if ((subframe_len = decode_subframe_length(s, min_channel_len)) <= 0)
551 return AVERROR_INVALIDDATA;
552
553 /** add subframes to the individual channels and find new min_channel_len */
554 min_channel_len += subframe_len;
555 for (c = 0; c < s->num_channels; c++) {
556 WMAProChannelCtx* chan = &s->channel[c];
557
558 if (contains_subframe[c]) {
559 if (chan->num_subframes >= MAX_SUBFRAMES) {
560 av_log(s->avctx, AV_LOG_ERROR,
561 "broken frame: num subframes > 31\n");
562 return AVERROR_INVALIDDATA;
563 }
564 chan->subframe_len[chan->num_subframes] = subframe_len;
565 num_samples[c] += subframe_len;
566 ++chan->num_subframes;

Callers 1

decode_frameFunction · 0.85

Calls 3

get_bits1Function · 0.85
decode_subframe_lengthFunction · 0.85
av_logFunction · 0.85

Tested by

no test coverage detected