[vlc-commits] mux: mp4: set interlacing for YUV formats
Francois Cartegnie
git at videolan.org
Tue Jan 21 16:46:18 CET 2020
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Jan 20 20:19:14 2020 +0100| [eb7ed18018293bb6b4286e5b3f376212b63c2074] | committer: Francois Cartegnie
mux: mp4: set interlacing for YUV formats
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=eb7ed18018293bb6b4286e5b3f376212b63c2074
---
modules/mux/mp4/libmp4mux.c | 40 +++++++++++++++++++++++++++++++++++-----
modules/mux/mp4/libmp4mux.h | 9 +++++++++
modules/mux/mp4/mp4.c | 13 +++++++++++++
3 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/modules/mux/mp4/libmp4mux.c b/modules/mux/mp4/libmp4mux.c
index 90eeb2eb6d..e27b7258d1 100644
--- a/modules/mux/mp4/libmp4mux.c
+++ b/modules/mux/mp4/libmp4mux.c
@@ -60,6 +60,7 @@ struct mp4mux_trackinfo_t
vlc_tick_t i_read_duration;
uint32_t i_timescale;
bool b_hasbframes;
+ enum mp4mux_interlacing e_interlace;
/* frags */
vlc_tick_t i_trex_default_length;
@@ -282,6 +283,16 @@ uint32_t mp4mux_track_GetID(const mp4mux_trackinfo_t *t)
return t->i_track_id;
}
+void mp4mux_track_SetInterlacing(mp4mux_trackinfo_t *t, enum mp4mux_interlacing i)
+{
+ t->e_interlace = i;
+}
+
+enum mp4mux_interlacing mp4mux_track_GetInterlacing(const mp4mux_trackinfo_t *t)
+{
+ return t->e_interlace;
+}
+
void mp4mux_track_SetSamplePriv(mp4mux_trackinfo_t *t,
const uint8_t *p_data, size_t i_data)
{
@@ -869,6 +880,23 @@ static bo_t *GetxxxxTag(const uint8_t *p_extra, size_t i_extra,
return box;
}
+static bo_t *GetFielBox(enum mp4mux_interlacing i)
+{
+ bo_t *p_box = box_new("fiel");
+ if(p_box)
+ {
+ const uint16_t values[] =
+ {
+ [INTERLACING_NONE] = 0x0100,
+ [INTERLACING_SINGLE_FIELD] = 0x0200,
+ [INTERLACING_TOPBOTTOM] = 0x0201,
+ [INTERLACING_BOTTOMTOP ] = 0x0206,
+ };
+ bo_add_16be(p_box, values[i]);
+ }
+ return p_box;
+}
+
static bo_t *GetColrBox(const video_format_t *p_vfmt, bool b_mov)
{
bo_t *p_box = box_new("colr");
@@ -1174,7 +1202,7 @@ static bo_t *GetVideBox(vlc_object_t *p_obj, mp4mux_trackinfo_t *p_track, bool b
VLC_UNUSED(p_obj);
char fcc[4];
- bool b_colr = false;
+ bool b_colr = false, b_fiel = false;
static_assert(VLC_CODEC_YUV4 == VLC_FOURCC('y','u','v','4'), "incorrect fcc for yuv4");
static_assert(VLC_CODEC_V210 == VLC_FOURCC('v','2','1','0'), "incorrect fcc for v210");
@@ -1195,16 +1223,16 @@ static bo_t *GetVideBox(vlc_object_t *p_obj, mp4mux_trackinfo_t *p_track, bool b
/* FIXME: find a way to know if no non-VCL units are in the stream (->hvc1)
* see 14496-15 8.4.1.1.1 */
case VLC_CODEC_HEVC: memcpy(fcc, "hev1", 4); break;
- case VLC_CODEC_YV12: memcpy(fcc, "yv12", 4); b_colr = true; break;
- case VLC_CODEC_YUYV: memcpy(fcc, "YUY2", 4); b_colr = true; break;
- case VLC_CODEC_UYVY: memcpy(fcc, "2vuy", 4); b_colr = true; break;
+ case VLC_CODEC_YV12: memcpy(fcc, "yv12", 4); b_colr = b_fiel = true; break;
+ case VLC_CODEC_YUYV: memcpy(fcc, "YUY2", 4); b_colr = b_fiel= true; break;
+ case VLC_CODEC_UYVY: memcpy(fcc, "2vuy", 4); b_colr = b_fiel= true; break;
case VLC_CODEC_YUV4:
case VLC_CODEC_V210:
case VLC_CODEC_V308:
case VLC_CODEC_V408:
case VLC_CODEC_V410:
vlc_fourcc_to_char(p_track->fmt.i_codec, fcc);
- b_colr = true;
+ b_colr = b_fiel = true;
break;
default:
vlc_fourcc_to_char(p_track->fmt.i_codec, fcc);
@@ -1293,6 +1321,8 @@ static bo_t *GetVideBox(vlc_object_t *p_obj, mp4mux_trackinfo_t *p_track, bool b
if(b_colr)
box_gather(vide, GetColrBox(&p_track->fmt.video, b_mov));
+ if(b_fiel)
+ box_gather(vide, GetFielBox(p_track->e_interlace));
box_gather(vide, GetMdcv(&p_track->fmt.video));
box_gather(vide, GetClli(&p_track->fmt.video));
diff --git a/modules/mux/mp4/libmp4mux.h b/modules/mux/mp4/libmp4mux.h
index 11b059d3e9..0d070cdb81 100644
--- a/modules/mux/mp4/libmp4mux.h
+++ b/modules/mux/mp4/libmp4mux.h
@@ -50,6 +50,15 @@ vlc_tick_t mp4mux_track_GetDuration(const mp4mux_trackinfo_t *);
void mp4mux_track_ForceDuration(mp4mux_trackinfo_t *, vlc_tick_t); /* Used by frag */
bool mp4mux_track_HasBFrames(const mp4mux_trackinfo_t *);
void mp4mux_track_SetHasBFrames(mp4mux_trackinfo_t *);
+enum mp4mux_interlacing
+{
+ INTERLACING_NONE = 0,
+ INTERLACING_SINGLE_FIELD = 1,
+ INTERLACING_TOPBOTTOM = 2,
+ INTERLACING_BOTTOMTOP = 3,
+};
+void mp4mux_track_SetInterlacing(mp4mux_trackinfo_t *, enum mp4mux_interlacing);
+enum mp4mux_interlacing mp4mux_track_GetInterlacing(const mp4mux_trackinfo_t *);
void mp4mux_track_SetSamplePriv(mp4mux_trackinfo_t *, const uint8_t *, size_t);
bool mp4mux_track_HasSamplePriv(const mp4mux_trackinfo_t *);
vlc_tick_t mp4mux_track_GetDefaultSampleDuration(const mp4mux_trackinfo_t *);
diff --git a/modules/mux/mp4/mp4.c b/modules/mux/mp4/mp4.c
index a32673cd10..7e99969b6a 100644
--- a/modules/mux/mp4/mp4.c
+++ b/modules/mux/mp4/mp4.c
@@ -749,6 +749,19 @@ static int MuxStream(sout_mux_t *p_mux, sout_input_t *p_input, mp4_stream_t *p_s
}
}
+ /* Flag interlacing on first block */
+ if(mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == VIDEO_ES &&
+ (p_data->i_flags & BLOCK_FLAG_INTERLACED_MASK) &&
+ mp4mux_track_GetInterlacing(p_stream->tinfo) == INTERLACING_NONE)
+ {
+ if(p_data->i_flags & BLOCK_FLAG_SINGLE_FIELD)
+ mp4mux_track_SetInterlacing(p_stream->tinfo, INTERLACING_SINGLE_FIELD);
+ else if(p_data->i_flags & BLOCK_FLAG_TOP_FIELD_FIRST)
+ mp4mux_track_SetInterlacing(p_stream->tinfo, INTERLACING_TOPBOTTOM);
+ else
+ mp4mux_track_SetInterlacing(p_stream->tinfo, INTERLACING_BOTTOMTOP);
+ }
+
/* Update (Not earlier for SPU!) */
p_stream->i_last_dts = dts_fb_pts( p_data );
if( p_data->i_pts > p_stream->i_last_pts )
More information about the vlc-commits
mailing list