forked from FFmpeg/FFmpeg
avformat/dvdvideodec: standardize the NAV packet event signal
This consolidates the FFERROR_REDO handling of NAV packets to dvdvideo_subdemux_read_data(), is a pre-requisite to calculating chapter markers for menus, and a pre-requisite to fixing the frame desync issue when the subdemuxer is flushed. Signed-off-by: Marth64 <marth64@proxyid.net>
This commit is contained in:
parent
6bbaa7db49
commit
b38ca20bf2
1 changed files with 17 additions and 14 deletions
|
@ -390,7 +390,7 @@ static int dvdvideo_menu_open(AVFormatContext *s, DVDVideoPlaybackState *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dvdvideo_menu_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState *state,
|
static int dvdvideo_menu_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState *state,
|
||||||
uint8_t *buf, int buf_size,
|
uint8_t *buf, int buf_size, int *p_is_nav_packet,
|
||||||
void (*flush_cb)(AVFormatContext *s))
|
void (*flush_cb)(AVFormatContext *s))
|
||||||
{
|
{
|
||||||
int64_t blocks_read = 0;
|
int64_t blocks_read = 0;
|
||||||
|
@ -398,6 +398,8 @@ static int dvdvideo_menu_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState
|
||||||
pci_t pci = (pci_t) {0};
|
pci_t pci = (pci_t) {0};
|
||||||
dsi_t dsi = (dsi_t) {0};
|
dsi_t dsi = (dsi_t) {0};
|
||||||
|
|
||||||
|
(*p_is_nav_packet) = 0;
|
||||||
|
|
||||||
if (buf_size != DVDVIDEO_BLOCK_SIZE) {
|
if (buf_size != DVDVIDEO_BLOCK_SIZE) {
|
||||||
av_log(s, AV_LOG_ERROR, "Invalid buffer size (expected=%d actual=%d)\n",
|
av_log(s, AV_LOG_ERROR, "Invalid buffer size (expected=%d actual=%d)\n",
|
||||||
DVDVIDEO_BLOCK_SIZE, buf_size);
|
DVDVIDEO_BLOCK_SIZE, buf_size);
|
||||||
|
@ -481,7 +483,9 @@ static int dvdvideo_menu_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState
|
||||||
dsi.dsi_gi.nv_pck_lbn,
|
dsi.dsi_gi.nv_pck_lbn,
|
||||||
pci.pci_gi.vobu_s_ptm, pci.pci_gi.vobu_e_ptm, state->ts_offset);
|
pci.pci_gi.vobu_s_ptm, pci.pci_gi.vobu_e_ptm, state->ts_offset);
|
||||||
|
|
||||||
return FFERROR_REDO;
|
(*p_is_nav_packet) = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we are in the middle of a VOBU, so pass on the PS packet */
|
/* we are in the middle of a VOBU, so pass on the PS packet */
|
||||||
|
@ -611,8 +615,7 @@ end_dvdnav_error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState *state,
|
static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState *state,
|
||||||
uint8_t *buf, int buf_size,
|
uint8_t *buf, int buf_size, int *p_is_nav_packet,
|
||||||
int *p_nav_event,
|
|
||||||
void (*flush_cb)(AVFormatContext *s))
|
void (*flush_cb)(AVFormatContext *s))
|
||||||
{
|
{
|
||||||
DVDVideoDemuxContext *c = s->priv_data;
|
DVDVideoDemuxContext *c = s->priv_data;
|
||||||
|
@ -627,6 +630,8 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState
|
||||||
pci_t *e_pci;
|
pci_t *e_pci;
|
||||||
dsi_t *e_dsi;
|
dsi_t *e_dsi;
|
||||||
|
|
||||||
|
(*p_is_nav_packet) = 0;
|
||||||
|
|
||||||
if (buf_size != DVDVIDEO_BLOCK_SIZE) {
|
if (buf_size != DVDVIDEO_BLOCK_SIZE) {
|
||||||
av_log(s, AV_LOG_ERROR, "Invalid buffer size (expected=%d actual=%d)\n",
|
av_log(s, AV_LOG_ERROR, "Invalid buffer size (expected=%d actual=%d)\n",
|
||||||
DVDVIDEO_BLOCK_SIZE, buf_size);
|
DVDVIDEO_BLOCK_SIZE, buf_size);
|
||||||
|
@ -780,9 +785,9 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState
|
||||||
|
|
||||||
state->vobu_e_ptm = e_pci->pci_gi.vobu_e_ptm;
|
state->vobu_e_ptm = e_pci->pci_gi.vobu_e_ptm;
|
||||||
|
|
||||||
(*p_nav_event) = nav_event;
|
(*p_is_nav_packet) = 1;
|
||||||
|
|
||||||
return nav_len;
|
return 0;
|
||||||
case DVDNAV_BLOCK_OK:
|
case DVDNAV_BLOCK_OK:
|
||||||
if (!state->in_ps) {
|
if (!state->in_ps) {
|
||||||
if (state->in_pgc)
|
if (state->in_pgc)
|
||||||
|
@ -811,8 +816,6 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState
|
||||||
|
|
||||||
memcpy(buf, &nav_buf, nav_len);
|
memcpy(buf, &nav_buf, nav_len);
|
||||||
|
|
||||||
(*p_nav_event) = nav_event;
|
|
||||||
|
|
||||||
state->is_seeking = 0;
|
state->is_seeking = 0;
|
||||||
|
|
||||||
return nav_len;
|
return nav_len;
|
||||||
|
@ -1442,18 +1445,18 @@ static int dvdvideo_subdemux_read_data(void *opaque, uint8_t *buf, int buf_size)
|
||||||
AVFormatContext *s = opaque;
|
AVFormatContext *s = opaque;
|
||||||
DVDVideoDemuxContext *c = s->priv_data;
|
DVDVideoDemuxContext *c = s->priv_data;
|
||||||
|
|
||||||
int ret = 0;
|
int ret;
|
||||||
int nav_event;
|
int is_nav_packet;
|
||||||
|
|
||||||
if (c->play_end)
|
if (c->play_end)
|
||||||
return AVERROR_EOF;
|
return AVERROR_EOF;
|
||||||
|
|
||||||
if (c->opt_menu)
|
if (c->opt_menu)
|
||||||
ret = dvdvideo_menu_next_ps_block(s, &c->play_state, buf, buf_size,
|
ret = dvdvideo_menu_next_ps_block(s, &c->play_state, buf, buf_size, &is_nav_packet,
|
||||||
dvdvideo_subdemux_flush);
|
dvdvideo_subdemux_flush);
|
||||||
else
|
else
|
||||||
ret = dvdvideo_play_next_ps_block(opaque, &c->play_state, buf, buf_size,
|
ret = dvdvideo_play_next_ps_block(s, &c->play_state, buf, buf_size, &is_nav_packet,
|
||||||
&nav_event, dvdvideo_subdemux_flush);
|
dvdvideo_subdemux_flush);
|
||||||
|
|
||||||
if (ret == AVERROR_EOF) {
|
if (ret == AVERROR_EOF) {
|
||||||
c->mpeg_pb.pub.eof_reached = 1;
|
c->mpeg_pb.pub.eof_reached = 1;
|
||||||
|
@ -1462,7 +1465,7 @@ static int dvdvideo_subdemux_read_data(void *opaque, uint8_t *buf, int buf_size)
|
||||||
return AVERROR_EOF;
|
return AVERROR_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret >= 0 && nav_event == DVDNAV_NAV_PACKET)
|
if (ret == 0 && is_nav_packet)
|
||||||
return FFERROR_REDO;
|
return FFERROR_REDO;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Reference in a new issue