diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index a6fc61b..47d97b8 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2013.01.08.144634" +#define Cdrskin_timestamP "2013.01.12.195030" diff --git a/libburn/libburn.h b/libburn/libburn.h index bd9b748..c325548 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -343,7 +343,6 @@ enum burn_drive_status "session", "point", "pmin", ... Do not rely on the current size of a burn_toc_entry. - ts A70201 : DVD extension, see below */ struct burn_toc_entry { @@ -372,6 +371,8 @@ struct burn_toc_entry older elements in this structure: bit0= DVD extension is valid @since 0.3.2 @since 0.5.2 : DVD extensions are made valid for CD too + bit1= LRA extension is valid @since 0.7.2 + bit2= Track status bits extension is valid @since 1.2.8 */ unsigned char extensions_valid; @@ -393,6 +394,24 @@ struct burn_toc_entry This would mean profiles: 0x11, 0x15, 0x13, 0x14, 0x51, 0x41, 0x42 */ int last_recorded_address; + + /* ts B30112 : Track status bits extension. extensions_valid:bit2 */ + /* @since 1.2.8 */ + /* Names as of READ TRACK INFORMATION, MMC-5 6.27.3 : + bit0 - bit3 = Track Mode + bit4 = Copy + bit5 = Damage + bit6 - bit7 = LJRS + bit8 - bit11 = Data Mode + bit12 = FP + bit13 = Packet/Inc + bit14 = Blank + bit15 = RT + bit16 = NWA_V + bit17 = LRA_V + */ + int track_status_bits; + }; @@ -3387,8 +3406,12 @@ void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry); void burn_session_get_leadout_entry(struct burn_session *s, struct burn_toc_entry *entry); -/** Gets an array of all the sessions for the disc +/** Gets an array of all complete sessions for the disc THIS IS NO LONGER VALID AFTER YOU ADD OR REMOVE A SESSION + The result array contains *num + burn_disc_get_open_sessions() + elements. All above *num are incomplete sessions. + Typically there is one incomplete session with one empty track. + DVD+R and BD-R seem to allow more than one track with even readable data. @param d Disc to get session array for @param num Returns the number of sessions in the array @return array of sessions @@ -3396,6 +3419,17 @@ void burn_session_get_leadout_entry(struct burn_session *s, struct burn_session **burn_disc_get_sessions(struct burn_disc *d, int *num); +/* ts B30112 */ +/* @since 1.2.8 */ +/** Obtains the number of incomplete sessions which are recorded in the + result array of burn_disc_get_sessions() after the complete sessions. + See above. + @param d Disc object to inquire + @return Number of incomplete sessions +*/ +int burn_disc_get_incomplete_sessions(struct burn_disc *d); + + int burn_disc_get_sectors(struct burn_disc *d); /** Gets an array of all the tracks for a session @@ -4048,6 +4082,12 @@ BURN_END_DECLS */ #define Libburn_dummy_probe_write_modeS 1 +/* ts B30112 */ +/* Handle DVD+R with reserved tracks in incomplete first session + by loading info about the incomplete session into struct burn_disc +*/ +#define Libburn_disc_with_incomplete_sessioN 1 + /* Early experimental: Do not define Libburn_develop_quality_scaN unless you want to work diff --git a/libburn/libburn.ver b/libburn/libburn.ver index 546e06d..21f0c77 100644 --- a/libburn/libburn.ver +++ b/libburn/libburn.ver @@ -19,6 +19,7 @@ burn_disc_get_bd_spare_info; burn_disc_get_cd_info; burn_disc_get_format_descr; burn_disc_get_formats; +burn_disc_get_incomplete_sessions; burn_disc_get_leadin_text; burn_disc_get_media_id; burn_disc_get_msc1; diff --git a/libburn/mmc.c b/libburn/mmc.c index 450145f..33a8488 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -1126,6 +1126,12 @@ err_ex:; if (dlen + 2 > old_alloc_len) dlen = old_alloc_len - 2; d->complete_sessions = 1 + c->page->data[3] - c->page->data[2]; + +#ifdef Libburn_disc_with_incomplete_sessioN + /* ts B30112 : number of open sessions */ + d->incomplete_sessions = 0; +#endif + d->last_track_no = d->complete_sessions; if (dlen - 2 < (d->last_track_no + 1) * 8) { libdax_msgs_submit(libdax_messenger, d->global_index, @@ -1253,9 +1259,22 @@ int mmc_fake_toc(struct burn_drive *d) {ret = -1; goto ex;} BURN_ALLOC_MEM(buf, struct buffer, 1); +#ifdef Libburn_disc_with_incomplete_sessioN + + if (d->last_track_no <= 0 || + d->complete_sessions + d->incomplete_sessions <= 0 || + d->status == BURN_DISC_BLANK) + {ret = 2; goto ex;} + +#else + if (d->last_track_no <= 0 || d->complete_sessions <= 0 || d->status == BURN_DISC_BLANK) {ret = 2; goto ex;} + +#endif /* ! Libburn_disc_with_incomplete_sessioN */ + + if (d->last_track_no > BURN_MMC_FAKE_TOC_MAX_SIZE) { msg = calloc(1, 160); if (msg != NULL) { @@ -1279,18 +1298,34 @@ int mmc_fake_toc(struct burn_drive *d) d->disc = burn_disc_create(); if (d->disc == NULL) {ret = -1; goto ex;} - d->toc_entries = d->last_track_no + d->complete_sessions; + d->toc_entries = d->last_track_no + + d->complete_sessions + d->incomplete_sessions; d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry)); if (d->toc_entry == NULL) {ret = -1; goto ex;} memset(d->toc_entry, 0,d->toc_entries * sizeof(struct burn_toc_entry)); + +#ifdef Libburn_disc_with_incomplete_sessioN + + for (i = 0; i < d->complete_sessions + d->incomplete_sessions; i++) { + +#else + for (i = 0; i < d->complete_sessions; i++) { + +#endif + session = burn_session_create(); if (session == NULL) {ret = -1; goto ex;} burn_disc_add_session(d->disc, session, BURN_POS_END); burn_session_free(session); } + +#ifdef Libburn_disc_with_incomplete_sessioN + d->disc->incomplete_sessions = d->incomplete_sessions; +#endif + memset(size_data, 0, 4); memset(start_data, 0, 4); @@ -1333,7 +1368,16 @@ int mmc_fake_toc(struct burn_drive *d) entry; } +#ifdef Libburn_disc_with_incomplete_sessioN + + if (session_number > d->complete_sessions) { + +#else + if (session_number > d->disc->sessions) { + +#endif + if (i == d->last_track_no - 1) { /* ts A70212 : Last track field Free Blocks */ burn_drive_set_media_capacity_remaining(d, @@ -1341,7 +1385,18 @@ int mmc_fake_toc(struct burn_drive *d) ((off_t) 2048)); d->media_lba_limit = 0; } + +#ifdef Libburn_disc_with_incomplete_sessioN + + if (session_number > d->disc->sessions ) continue; + +#else + + continue; + +#endif + } entry = &(d->toc_entry[i + session_number - 1]); @@ -1359,12 +1414,16 @@ int mmc_fake_toc(struct burn_drive *d) memcpy(end_data, tdata + 28, 4); mmc_fake_toc_entry(entry, session_number, i + 1, size_data, start_data, end_data); + entry->track_status_bits = tdata[5] | (tdata[6] << 8) | + (tdata[7] << 16); + entry->extensions_valid |= 4; if (prev_session != session_number) d->disc->session[session_number - 1]->firsttrack = i+1; d->disc->session[session_number - 1]->lasttrack = i+1; prev_session = session_number; } + if (prev_session > 0 && prev_session <= d->disc->sessions) { /* leadout entry of last session of closed disc */ entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]); @@ -2029,16 +2088,28 @@ regard_as_blank:; d->current_profile == 0x12 || d->current_profile == 0x43) d->status = BURN_DISC_BLANK; +#ifdef Libburn_disc_with_incomplete_sessioN + /* ts B30112 : number of open sessions */ + d->incomplete_sessions = 0; +#endif + if (d->status == BURN_DISC_BLANK) { d->last_track_no = 1; /* The "incomplete track" */ d->complete_sessions = 0; } else { - /* ts A70131 : number of non-empty sessions */ + /* ts A70131 : number of closed sessions */ d->complete_sessions = number_of_sessions; /* mmc5r03c.pdf 6.22.3.1.3 State of Last Session: 3=complete */ - if (d->state_of_last_session != 3 && d->complete_sessions >= 1) + if (d->state_of_last_session != 3 && + d->complete_sessions >= 1) { d->complete_sessions--; +#ifdef Libburn_disc_with_incomplete_sessioN + d->incomplete_sessions++; +#endif + + } + /* ts A70129 : mmc5r03c.pdf 6.22.3.1.7 This includes the "incomplete track" if the disk is appendable. I.e number of complete tracks + 1. */ @@ -5014,6 +5085,11 @@ int mmc_setup_drive(struct burn_drive *d) d->disc_info_valid = 0; d->num_format_descr = 0; d->complete_sessions = 0; + +#ifdef Libburn_disc_with_incomplete_sessioN + d->incomplete_sessions = 0; +#endif + d->state_of_last_session = -1; d->last_track_no = 1; d->media_capacity_remaining = 0; diff --git a/libburn/structure.c b/libburn/structure.c index 766e9b3..e16034c 100644 --- a/libburn/structure.c +++ b/libburn/structure.c @@ -65,6 +65,11 @@ struct burn_disc *burn_disc_create(void) d->refcnt = 1; d->sessions = 0; d->session = NULL; + +#ifdef Libburn_disc_with_incomplete_sessioN + d->incomplete_sessions= 0; +#endif + return d; } @@ -691,10 +696,37 @@ void burn_session_get_leadout_entry(struct burn_session *s, struct burn_session **burn_disc_get_sessions(struct burn_disc *d, int *num) { + +#ifdef Libburn_disc_with_incomplete_sessioN + + *num = d->sessions - d->incomplete_sessions; + +#else + *num = d->sessions; + +#endif + + return d->session; } + +/* ts B30112 : API */ +int burn_disc_get_incomplete_sessions(struct burn_disc *d) +{ +#ifdef Libburn_disc_with_incomplete_sessioN + + return d->incomplete_sessions; + +#else + + return 0; + +#endif +} + + struct burn_track **burn_session_get_tracks(struct burn_session *s, int *num) { *num = s->tracks; diff --git a/libburn/structure.h b/libburn/structure.h index 895bf8a..aaaff63 100644 --- a/libburn/structure.h +++ b/libburn/structure.h @@ -144,6 +144,11 @@ struct burn_disc { int sessions; struct burn_session **session; + +#ifdef Libburn_disc_with_incomplete_sessioN + int incomplete_sessions; +#endif + int refcnt; }; diff --git a/libburn/transport.h b/libburn/transport.h index bdaa495..3295e42 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -287,6 +287,12 @@ struct burn_drive /* ts A90107 */ int state_of_last_session; +#ifdef Libburn_disc_with_incomplete_sessioN + /* ts B30112 */ + int incomplete_sessions; +#endif + + /* ts A70129 : from 51h READ DISC INFORMATION Last Track Number in Last Session */ int last_track_no;