Audio-Scan

 view release on metacpan or  search on metacpan

src/mp4.c  view on Meta::CPAN

    value = newSVuv(size - 8);

    my_hv_store( mp4->tags, "COVR_offset", newSVuv(mp4->audio_offset + (mp4->size - mp4->rsize) + 24) );

    _mp4_skip(mp4, size);
  }
  else {
    // Read the full ilst value
    if ( !_check_buf(mp4->infile, mp4->buf, size, MP4_BLOCK_SIZE) ) {
      return 0;
    }

    // Version(0) + Flags
    flags = buffer_get_int(mp4->buf);

    // Skip reserved
    buffer_consume(mp4->buf, 4);

    DEBUG_TRACE("      flags %d\n", flags);

    if ( !flags || flags == 21 ) {
      if ( FOURCC_EQ( SvPVX(key), "TRKN" ) || FOURCC_EQ( SvPVX(key), "DISK" ) ) {
        // Special case trkn, disk (pair of 16-bit ints)
        uint16_t num = 0;
        uint16_t total = 0;

        buffer_consume(mp4->buf, 2); // padding

        num = buffer_get_short(mp4->buf);

        // Total may not always be present
        if (size > 12) {
          total = buffer_get_short(mp4->buf);
          buffer_consume(mp4->buf, size - 14); // optional padding
        }

        DEBUG_TRACE("      %d/%d\n", num, total);

        if (total) {
          my_hv_store_ent( mp4->tags, key, newSVpvf( "%d/%d", num, total ) );
        }
        else if (num) {
          my_hv_store_ent( mp4->tags, key, newSVuv(num) );
        }

        return 1;
      }
      else if ( FOURCC_EQ( SvPVX(key), "GNRE" ) ) {
        // Special case genre, 16-bit int as id3 genre code
        char const *genre_string;
        uint16_t genre_num = buffer_get_short(mp4->buf);

        if (genre_num > 0 && genre_num < NGENRES + 1) {
          genre_string = _id3_genre_index(genre_num - 1);
          my_hv_store_ent( mp4->tags, key, newSVpv( genre_string, 0 ) );
        }

        return 1;
      }
      else {
        // Other binary type, try to guess type based on size
        uint32_t dsize = size - 8;

        if (dsize == 1) {
          value = newSVuv( buffer_get_char(mp4->buf) );
        }
        else if (dsize == 2) {
          value = newSVuv( buffer_get_short(mp4->buf) );
        }
        else if (dsize == 4) {
          value = newSVuv( buffer_get_int(mp4->buf) );
        }
        else if (dsize == 8) {
          value = newSVuv( buffer_get_int64(mp4->buf) );
        }
        else {
          value = newSVpvn( buffer_ptr(mp4->buf), dsize );
          buffer_consume(mp4->buf, dsize);
        }
      }
    }
    else { // text data
      value = newSVpvn( buffer_ptr(mp4->buf), size - 8 );
      sv_utf8_decode(value);

      // strip copyright symbol 0xA9 out of key
      if ( ckey[0] == 0xA9 ) {
        ckey++;
      }

      DEBUG_TRACE("      %s = %s\n", ckey, SvPVX(value));

      buffer_consume(mp4->buf, size - 8);
    }
  }

  // if key exists, create array
  if ( my_hv_exists( mp4->tags, (char *)ckey ) ) {
    SV **entry = my_hv_fetch( mp4->tags, (char *)ckey );
    if (entry != NULL) {
      if ( SvROK(*entry) && SvTYPE(SvRV(*entry)) == SVt_PVAV ) {
        av_push( (AV *)SvRV(*entry), value );
      }
      else {
        // A non-array entry, convert to array.
        AV *ref = newAV();
        av_push( ref, newSVsv(*entry) );
        av_push( ref, value );
        my_hv_store( mp4->tags, (char *)ckey, newRV_noinc( (SV*)ref ) );
      }
    }
  }
  else {
    my_hv_store( mp4->tags, (char *)ckey, value );
  }

  return 1;
}

uint8_t
_mp4_parse_ilst_custom(mp4info *mp4, uint32_t size)



( run in 0.811 second using v1.01-cache-2.11-cpan-39bf76dae61 )