Add support for libx265 playback on iPhone and other MAC devices

hvc1 and hev1 are two different things.

hvc1 is HEVC video with the metadata for decoding it stored only in the container (meaning not in the video stream).

hev1 is the FFmpeg default tag, which indicates an HEVC video where metadata can be stored in the container or the stream.

Basically, Apple is the inflexible party here by insisting that metadata be stored only in the container. Or more likely, their insistence on signaling that metadata is only in the container, whether it is actually there or not.

People have already asked the FFmpeg developers to make hvc1 the default tag. The developers declined. They didn’t give their reasoning, but my guess would be that they did not (or could not) guarantee that metadata would only appear in the container to be hvc1 compliant. Note that libx265 is a separate software project from FFmpeg, with separate developers.

See request at FFmpeg bug tracker:
#6860 (hvc1 instead of hev1 in FourCC) – FFmpeg

In light of this, I think it would be dangerous to make the current Shotcut HEVC stock export presets use the hvc1 tag as a default. Perhaps it might be viable to create an additional HEVC export preset where the phrase “for Apple devices” is clearly indicated in the title for those willing to take the risk with hvc1. (This is just my opinion… I’m in no position to say what will actually happen.)

For now, the best solution is to make a custom export preset as @MusicalBox demonstrated and add vtag=hvc1 to the list before saving it. This would remove the need to run ffmpeg after export to add the tag manually. As a convenience, also adding meta.preset.extension=mp4 to the Other box would set the default extension to .mp4 so you wouldn’t have to add it yourself at every export.


For the uber-curious, note what happens in the metadata with the hvc1 override…

The container metadata:
ffprobe -i test.mp4 -show_format

[FORMAT]
filename=test.mp4
nb_streams=2
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=10.048000
size=776763
bit_rate=618441
probe_score=100
TAG:major_brand=isom
TAG:minor_version=512
TAG:compatible_brands=isomiso2mp41
TAG:encoder=Lavf58.29.100
[/FORMAT]

…which doesn’t contain much decoding metadata. Most of it is still in the stream (note the codec_tag_string=hvc1 override)…

ffprobe -i test.mp4 -show_entries stream

[STREAM]
index=0
codec_name=hevc
codec_long_name=H.265 / HEVC (High Efficiency Video Coding)
profile=Main 10
codec_type=video
codec_tag_string=hvc1
codec_tag=0x31637668
width=1920
height=1080
coded_width=1920
coded_height=1080
closed_captions=0
has_b_frames=2
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
pix_fmt=yuv420p10le
level=120
color_range=tv
color_space=bt709
color_transfer=bt709
color_primaries=bt709
chroma_location=left
field_order=progressive
refs=1
id=N/A
r_frame_rate=30000/1001
avg_frame_rate=30000/1001
time_base=1/30000
start_pts=0
start_time=0.000000
duration_ts=300300
duration=10.010000
bit_rate=606117
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=300
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
DISPOSITION:captions=0
DISPOSITION:descriptions=0
DISPOSITION:metadata=0
DISPOSITION:dependent=0
DISPOSITION:still_image=0
TAG:language=und
TAG:handler_name=VideoHandler
TAG:vendor_id=[0][0][0][0]
[/STREAM]

I didn’t take time to compare this file to the ISO spec to be certain, but I’m pretty sure this file does not totally qualify as HVC1-compliant despite the codec_tag_string being overridden to say it is. This is why I don’t think a request to change the default to HVC1 would get any traction… it wouldn’t be correct from a compliance standpoint and could cause problems with more strict playback systems. The fact that the file plays on Mac High Sierra seems to suggest that Apple’s decoder is more forgiving than it lets on, provided the file makes it through the hvc1 checkpoint. Why the checkpoint is still there is anyone’s guess.

3 Likes