[vlc-commits] bluray: fix displaying of still images

Petri Hintukainen git at videolan.org
Wed Feb 19 20:56:56 CET 2014


vlc | branch: master | Petri Hintukainen <phintuka at users.sourceforge.net> | Tue Feb 18 22:26:50 2014 +0200| [58813c05b83f753e2bcba43838e4b3957de2737c] | committer: Jean-Baptiste Kempf

bluray: fix displaying of still images

MPEG-TS demuxer does not flush last video frame if size of PES packet is unknown.
Packet is flushed only when TS packet with PUSI flag set is received.
Fix this by emitting (video) ts packet with PUSI flag set.
Add video sequence end code to payload so that also video decoder is flushed.
Set PES packet size in the payload so that it will be sent to decoder immediately.

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=58813c05b83f753e2bcba43838e4b3957de2737c
---

 modules/access/bluray.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/modules/access/bluray.c b/modules/access/bluray.c
index 08ca3a4..846132a 100644
--- a/modules/access/bluray.c
+++ b/modules/access/bluray.c
@@ -151,6 +151,7 @@ struct  demux_sys_t
     int                 i_spu_stream;   /* Selected subtitle stream. -1 if default */
     int                 i_video_stream;
     stream_t            *p_parser;
+    bool                b_flushed;
 
     /* Used to store bluray disc path */
     char                *psz_bd_path;
@@ -1396,6 +1397,58 @@ static int blurayControl(demux_t *p_demux, int query, va_list args)
     return VLC_SUCCESS;
 }
 
+/*****************************************************************************
+ * libbluray event handling
+ *****************************************************************************/
+
+static void streamFlush( demux_sys_t *p_sys )
+{
+    /*
+     * MPEG-TS demuxer does not flush last video frame if size of PES packet is unknown.
+     * Packet is flushed only when TS packet with PUSI flag set is received.
+     *
+     * Fix this by emitting (video) ts packet with PUSI flag set.
+     * Add video sequence end code to payload so that also video decoder is flushed.
+     * Set PES packet size in the payload so that it will be sent to decoder immediately.
+     */
+
+    if (p_sys->b_flushed)
+        return;
+
+    block_t *p_block = block_Alloc(192);
+    if (!p_block)
+        return;
+
+    static const uint8_t seq_end_pes[] = {
+        0x00, 0x00, 0x01, 0xe0, 0x00, 0x07, 0x80, 0x00, 0x00,  /* PES header */
+        0x00, 0x00, 0x01, 0xb7,                                /* PES payload: sequence end */
+    };
+    static const uint8_t vid_pusi_ts[] = {
+        0x00, 0x00, 0x00, 0x00,                /* TP extra header (ATC) */
+        0x47, 0x50, 0x11, 0x30,                /* TP header */
+        (192 - (4 + 5) - sizeof(seq_end_pes)), /* adaptation field length */
+        0x80,                                  /* adaptation field: discontinuity indicator */
+    };
+
+    memset(p_block->p_buffer, 0, 192);
+    memcpy(p_block->p_buffer, vid_pusi_ts, sizeof(vid_pusi_ts));
+    memcpy(p_block->p_buffer + 192 - sizeof(seq_end_pes), seq_end_pes, sizeof(seq_end_pes));
+    p_block->i_buffer = 192;
+
+    /* set correct sequence end code */
+    BLURAY_TITLE_INFO *title_info = bd_get_playlist_info(p_sys->bluray, p_sys->i_playlist, 0);
+    if (title_info) {
+        if (title_info->clips[0].video_streams[0].coding_type > 2) {
+            /* VC1 / H.264 sequence end */
+            p_block->p_buffer[191] = 0x0a;
+        }
+        bd_free_title_info(title_info);
+    }
+
+    stream_DemuxSend(p_sys->p_parser, p_block);
+    p_sys->b_flushed = true;
+}
+
 static void blurayResetStillImage( demux_t *p_demux )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
@@ -1430,6 +1483,13 @@ static void blurayStillImage( demux_t *p_demux, unsigned i_timeout )
             msg_Dbg(p_demux, "Still image (infinite)");
             p_sys->i_still_end_time = -1;
         }
+
+        /* flush demuxer and decoder (there won't be next video packet starting with ts PUSI) */
+        streamFlush(p_sys);
+
+        /* stop buffering */
+        bool b_empty;
+        es_out_Control( p_demux->out, ES_OUT_GET_EMPTY, &b_empty );
     }
 
     /* avoid busy loops (read returns no data) */
@@ -1638,5 +1698,7 @@ static int blurayDemux(demux_t *p_demux)
 
     stream_DemuxSend(p_sys->p_parser, p_block);
 
+    p_sys->b_flushed = false;
+
     return 1;
 }



More information about the vlc-commits mailing list