int64_t CBDDemuxer::BDByteStreamSeek(void *opaque, int64_t offset, int whence) { CBDDemuxer *demux = (CBDDemuxer *)opaque; BLURAY *bd = demux->m_pBD; int64_t pos = 0; if (whence == SEEK_SET) { pos = offset; } else if (whence == SEEK_CUR) { if (offset == 0) return bd_tell(bd); pos = bd_tell(bd) + offset; } else if (whence == SEEK_END) { pos = bd_get_title_size(bd) - offset; } else if (whence == AVSEEK_SIZE) { return bd_get_title_size(bd); } else return -1; if (pos < 0) pos = 0; int64_t achieved = bd_seek(bd, pos); if (pos > achieved) { offset = pos - achieved; DbgLog((LOG_TRACE, 10, L"BD Seek to %I64d, achieved %I64d, correcting target by %I64d", pos, achieved, offset)); uint8_t *dump_buffer = (uint8_t *)CoTaskMemAlloc(6144); while (offset > 0) { bd_read(bd, dump_buffer, min(offset, 6144)); offset -= 6144; } CoTaskMemFree(dump_buffer); achieved = bd_tell(bd); } return achieved; }
JNIEXPORT jlong JNICALL Java_org_videolan_Libbluray_seekN(JNIEnv * env, jclass cls, jlong np, jlong pos) { BDJAVA* bdj = (BDJAVA*)(intptr_t)np; BD_DEBUG(DBG_JNI, "seekN(%"PRId64")\n", (int64_t)pos); return bd_seek(bdj->bd, pos); }
/*********************************************************************** * hb_bd_seek *********************************************************************** * **********************************************************************/ int hb_bd_seek( hb_bd_t * d, float f ) { uint64_t packet = f * d->pkt_count; bd_seek(d->bd, packet * 192); d->next_chap = bd_get_current_chapter( d->bd ) + 1; hb_ts_stream_reset(d->stream); return 1; }
static uint64_t align_to_next_packet(BLURAY *bd, uint8_t *pkt) { uint8_t buf[MAX_HOLE]; uint64_t pos = 0; uint64_t start = bd_tell(bd); uint64_t orig; uint64_t off = 192; memcpy(buf, pkt, 192); if ( start >= 192 ) { start -= 192; } orig = start; while (1) { if (bd_read(bd, buf+off, sizeof(buf)-off) == sizeof(buf)-off) { const uint8_t *bp = buf; int i; for ( i = sizeof(buf) - 8 * 192; --i >= 0; ++bp ) { if ( have_ts_sync( bp, 192 ) ) { break; } } if ( i >= 0 ) { pos = ( bp - buf ); break; } off = 8 * 192; memcpy(buf, buf + sizeof(buf) - off, off); start += sizeof(buf) - off; } else { return 0; } } off = start + pos - 4; // bd_seek seeks to the nearest access unit *before* the requested position // we don't want to seek backwards, so we need to read until we get // past that position. bd_seek(bd, off); while (off > bd_tell(bd)) { if (bd_read(bd, buf, 192) != 192) { break; } } return start - orig + pos; }
static int bluray_stream_seek(stream_t *s, int64_t pos) { struct bluray_priv_s *b = s->priv; int64_t p; p = bd_seek(b->bd, pos); if (p == -1) return 0; s->pos = p; return 1; }
static void _read_to_eof(BLURAY *bd) { BD_EVENT ev; int bytes; uint64_t total = 0; uint8_t buf[6144]; bd_seek(bd, bd_get_title_size(bd) - 6144); do { bytes = bd_read_ext(bd, buf, 6144, &ev); total += bytes < 0 ? 0 : bytes; _print_event(&ev); } while (bytes > 0); printf("_read_to_eof(): read %"PRIu64" bytes\n", total); }
static int bluray_stream_seek(stream_t *s, int64_t pos) { struct bluray_priv_s *b = s->priv; int64_t p; p = bd_seek(b->bd, pos); // bd_seek does not say what happens on errors, // so be extra paranoid. // bd_seek also does not seek exactly to the requested // position, so allow for some fuzz. if (p < 0 || p > pos || p + 20*1024*1024 < pos) { s->pos = bd_tell(b->bd); return 0; } s->pos = p; return 1; }
int64_t BDByteStreamSeek(void *opaque, int64_t offset, int whence) { BLURAY *bd = (BLURAY *)opaque; int64_t pos = 0; if (whence == SEEK_SET) { pos = offset; } else if (whence == SEEK_CUR) { if (offset == 0) return bd_tell(bd); pos = bd_tell(bd) + offset; } else if (whence == SEEK_END) { pos = bd_get_title_size(bd) - offset; } else if (whence == AVSEEK_SIZE) { return bd_get_title_size(bd); } else return -1; return bd_seek(bd, pos); }
/*********************************************************************** * hb_bd_read *********************************************************************** * **********************************************************************/ hb_buffer_t * hb_bd_read( hb_bd_t * d ) { int result; int error_count = 0; uint8_t buf[192]; BD_EVENT event; uint64_t pos; hb_buffer_t * out = NULL; uint8_t discontinuity; while ( 1 ) { discontinuity = 0; result = next_packet( d->bd, buf ); if ( result < 0 ) { hb_error("bd: Read Error"); pos = bd_tell( d->bd ); bd_seek( d->bd, pos + 192 ); error_count++; if (error_count > 10) { hb_error("bd: Error, too many consecutive read errors"); hb_set_work_error(d->h, HB_ERROR_READ); return NULL; } continue; } else if ( result == 0 ) { return NULL; } error_count = 0; while ( bd_get_event( d->bd, &event ) ) { switch ( event.event ) { case BD_EVENT_CHAPTER: // The muxers expect to only get chapter 2 and above // They write chapter 1 when chapter 2 is detected. if (event.param > d->chapter) { d->next_chap = event.param; } break; case BD_EVENT_PLAYITEM: discontinuity = 1; hb_deep_log(2, "bd: Playitem %u", event.param); break; case BD_EVENT_STILL: bd_read_skip_still( d->bd ); break; default: break; } } // buf+4 to skip the BD timestamp at start of packet if (d->chapter != d->next_chap) { d->chapter = d->next_chap; out = hb_ts_decode_pkt(d->stream, buf+4, d->chapter, discontinuity); } else { out = hb_ts_decode_pkt(d->stream, buf+4, 0, discontinuity); } if (out != NULL) { return out; } } return NULL; }
/*********************************************************************** * hb_bd_read *********************************************************************** * **********************************************************************/ hb_buffer_t * hb_bd_read( hb_bd_t * d ) { int result; int error_count = 0; uint8_t buf[192]; BD_EVENT event; uint64_t pos; hb_buffer_t * b; uint8_t discontinuity; int new_chap = 0; discontinuity = 0; while ( 1 ) { if ( d->next_chap != d->chapter ) { new_chap = d->chapter = d->next_chap; } result = next_packet( d->bd, buf ); if ( result < 0 ) { hb_error("bd: Read Error"); pos = bd_tell( d->bd ); bd_seek( d->bd, pos + 192 ); error_count++; if (error_count > 10) { hb_error("bd: Error, too many consecutive read errors"); return 0; } continue; } else if ( result == 0 ) { return 0; } error_count = 0; while ( bd_get_event( d->bd, &event ) ) { switch ( event.event ) { case BD_EVENT_CHAPTER: // The muxers expect to only get chapter 2 and above // They write chapter 1 when chapter 2 is detected. d->next_chap = event.param; break; case BD_EVENT_PLAYITEM: discontinuity = 1; hb_deep_log(2, "bd: Playitem %u", event.param); break; case BD_EVENT_STILL: bd_read_skip_still( d->bd ); break; default: break; } } // buf+4 to skip the BD timestamp at start of packet b = hb_ts_decode_pkt( d->stream, buf+4 ); if ( b ) { b->s.discontinuity = discontinuity; b->s.new_chap = new_chap; return b; } } return NULL; }