Audio-Scan
view release on metacpan or search on metacpan
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 )