Ticket #3041: mythmusic_lengthcalc_new.diff
File mythmusic_lengthcalc_new.diff, 5.8 KB (added by , 17 years ago) |
---|
-
mythmusic/mythmusic/metaioid3v2.cpp
12 12 13 13 #include "metaio_libid3hack.h" 14 14 15 16 15 #include <mythtv/mythcontext.h> 17 16 18 17 //========================================================================== … … 241 240 free(p_utf8); 242 241 } 243 242 243 //length = getComment(tag, "TLEN").toInt(); 244 244 245 id3_file_close(p_input); 245 246 } 246 247 … … 250 251 readFromFilename(filename, artist, album, title, genre, tracknum); 251 252 } 252 253 253 length = getTrackLength(filename); 254 if (length <= 0) 255 length = getTrackLength(filename); 254 256 255 257 // If we don't have title and artist or don't have the length return NULL 256 258 if ((title.isEmpty() && artist.isEmpty()) || length<=0) … … 262 264 263 265 Metadata *retdata = new Metadata(filename, artist, compilation_artist, album, 264 266 title, genre, year, tracknum, length); 265 267 266 268 retdata->setCompilation(compilation); 267 269 268 270 return retdata; … … 280 282 { 281 283 struct mad_stream stream; 282 284 struct mad_header header; 285 struct mad_frame frame; 283 286 mad_timer_t timer; 284 287 285 288 unsigned char buffer[8192]; … … 287 290 288 291 mad_stream_init(&stream); 289 292 mad_header_init(&header); 290 293 mad_frame_init(&frame); 294 291 295 timer = mad_timer_zero; 292 296 293 297 FILE *input = fopen(filename.local8Bit(), "r"); … … 340 344 } 341 345 else 342 346 { 347 348 if (amount_checked == 0) 349 { 350 frame.header = header; 351 if (mad_frame_decode(&frame, &stream) == -1) 352 { 353 if (!MAD_RECOVERABLE(stream.error)) 354 { 355 VERBOSE(VB_IMPORTANT, "Unrecoverable libmad stream error."); 356 break; 357 } 358 } 359 360 xing xing; 361 xing.frames = 0; 362 xing.bytes = 0; 363 364 if (findXingHeader(&xing, stream.anc_ptr, stream.anc_bitlen)) 365 { 366 unsigned long frames = xing.frames; 367 mad_timer_t duration = header.duration; 368 mad_timer_multiply(&duration, frames); 369 alt_length = mad_timer_count(duration, MAD_UNITS_MILLISECONDS); 370 loop_de_doo = false; 371 break; 372 } 373 } 374 343 375 if(amount_checked == 0) 344 376 { 345 377 old_bitrate = header.bitrate; … … 357 389 amount_checked++; 358 390 mad_timer_add(&timer, header.duration); 359 391 } 360 392 361 393 } 362 394 363 395 if (stream.error != MAD_ERROR_BUFLEN) 364 396 break; 365 397 … … 369 401 370 402 mad_header_finish(&header); 371 403 mad_stream_finish(&stream); 404 mad_frame_finish(&frame); 372 405 373 406 fclose(input); 374 407 … … 378 411 return alt_length; 379 412 } 380 413 414 bool MetaIOID3v2::findXingHeader(xing *xing, struct mad_bitptr ptr, unsigned int bitlen) 415 { 416 if (bitlen < 64 || mad_bit_read(&ptr, 32) != XING_MAGIC) 417 goto fail; 381 418 419 xing->flags = mad_bit_read(&ptr, 32); 420 bitlen -= 64; 421 422 if (xing->flags & XING_FRAMES) { 423 if (bitlen < 32) 424 goto fail; 425 426 xing->frames = mad_bit_read(&ptr, 32); 427 bitlen -= 32; 428 } 429 430 if (xing->flags & XING_BYTES) { 431 if (bitlen < 32) 432 goto fail; 433 434 xing->bytes = mad_bit_read(&ptr, 32); 435 bitlen -= 32; 436 } 437 438 if (xing->flags & XING_TOC) { 439 int i; 440 441 if (bitlen < 800) 442 goto fail; 443 444 for (i = 0; i < 100; ++i) 445 xing->toc[i] = mad_bit_read(&ptr, 8); 446 447 bitlen -= 800; 448 } 449 450 if (xing->flags & XING_SCALE) { 451 if (bitlen < 32) 452 goto fail; 453 454 xing->scale = mad_bit_read(&ptr, 32); 455 bitlen -= 32; 456 } 457 458 return true; 459 460 fail: 461 xing->flags = 0; 462 xing->frames = 0; 463 xing->bytes = 0; 464 xing->scale = 0; 465 return false; 466 } 467 382 468 inline QString MetaIOID3v2::getRawID3String(union id3_field *pField) 383 469 { 384 470 QString tmp = ""; -
mythmusic/mythmusic/metaioid3v2.h
12 12 #define MYTH_ID3_FRAME_COMMENT "TXXX" 13 13 #define MYTH_ID3_FRAME_MUSICBRAINZ_ALBUMARTISTDESC "MusicBrainz Album Artist Id" 14 14 15 #define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g') 16 17 typedef struct { 18 int flags; 19 unsigned long frames; 20 unsigned long bytes; 21 unsigned char toc[100]; 22 long scale; 23 } xing; 24 15 25 class MetaIOID3v2 : public MetaIO 16 26 { 17 27 public: 18 28 MetaIOID3v2(void); 19 29 virtual ~MetaIOID3v2(void); 20 30 21 31 bool write(Metadata* mdata, bool exclusive = false); 22 32 Metadata* read(QString filename); 23 33 24 34 private: 35 enum { 36 XING_FRAMES = 0x0001, 37 XING_BYTES = 0x0002, 38 XING_TOC = 0x0004, 39 XING_SCALE = 0x0008 40 }; 41 25 42 int getTrackLength(QString filename); 26 43 27 44 QString getRawID3String(union id3_field *pField); 28 45 void removeComment(id3_tag *pTag, const char* pLabel, const QString desc = ""); 29 46 QString getComment(id3_tag *pTag, const char* pLabel, 30 47 const QString desc = ""); 31 48 32 49 bool setComment(id3_tag *pTag, const char* pLabel, const QString value, 33 50 const QString desc = ""); 51 52 bool findXingHeader(xing *xing, struct mad_bitptr ptr, unsigned int bitlen); 34 53 }; 35 54 36 55 #endif