mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-02-17 04:17:05 +00:00
avformat/hlsenc: support CODECS Attribute in hevc EXT-X-STREAM-INF
fix ticket: 8904 parse the SPS from extradata and get profile_tier_level write the profile_tier_level info into CODECS Attribute HLS CODECS Attribute reference to :https://developer.apple.com/documentation/http_live_streaming/hls_authoring_specification_for_apple_devices/hls_authoring_specification_for_apple_devices_appendixes Signed-off-by: Steven Liu <lq@chinaffmpeg.org> Signed-off-by: liuqi05 <liuqi05@kuaishou.com>
This commit is contained in:
parent
b5ca8f2c66
commit
a2b1dd0ce3
@ -46,6 +46,7 @@
|
||||
|
||||
#include "avformat.h"
|
||||
#include "avio_internal.h"
|
||||
#include "avc.h"
|
||||
#if CONFIG_HTTP_PROTOCOL
|
||||
#include "http.h"
|
||||
#endif
|
||||
@ -337,6 +338,49 @@ static void write_codec_attr(AVStream *st, VariantStream *vs)
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
} else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
|
||||
uint8_t *data = st->codecpar->extradata;
|
||||
int profile = FF_PROFILE_UNKNOWN;
|
||||
int level = FF_LEVEL_UNKNOWN;
|
||||
|
||||
if (st->codecpar->profile != FF_PROFILE_UNKNOWN)
|
||||
profile = st->codecpar->profile;
|
||||
if (st->codecpar->level != FF_LEVEL_UNKNOWN)
|
||||
level = st->codecpar->level;
|
||||
|
||||
/* check the boundary of data which from current position is small than extradata_size */
|
||||
while (data && (data - st->codecpar->extradata + 5) < st->codecpar->extradata_size) {
|
||||
/* get HEVC SPS NAL and seek to profile_tier_level */
|
||||
if (!(data[0] | data[1] | data[2]) && data[3] == 1 && ((data[4] & 0x42) == 0x42)) {
|
||||
int remain_size = 0;
|
||||
int rbsp_size = 0;
|
||||
/* skip start code + nalu header */
|
||||
data += 6;
|
||||
/* process by reference General NAL unit syntax */
|
||||
remain_size = st->codecpar->extradata_size - (data - st->codecpar->extradata);
|
||||
uint8_t *rbsp_buf = ff_nal_unit_extract_rbsp(data, remain_size, &rbsp_size, 0);
|
||||
if (!rbsp_buf)
|
||||
return;
|
||||
if (rbsp_size < 13) {
|
||||
av_freep(&rbsp_buf);
|
||||
break;
|
||||
}
|
||||
/* skip sps_video_parameter_set_id u(4),
|
||||
* sps_max_sub_layers_minus1 u(3),
|
||||
* and sps_temporal_id_nesting_flag u(1) */
|
||||
profile = rbsp_buf[1] & 0x1f;
|
||||
/* skip 8 + 8 + 32 + 4 + 43 + 1 bit */
|
||||
level = rbsp_buf[12];
|
||||
av_freep(&rbsp_buf);
|
||||
break;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
if (st->codecpar->codec_tag == MKTAG('h','v','c','1') &&
|
||||
profile != FF_PROFILE_UNKNOWN &&
|
||||
level != FF_LEVEL_UNKNOWN) {
|
||||
snprintf(attr, sizeof(attr), "%s.%d.4.L%d.B01", av_fourcc2str(st->codecpar->codec_tag), profile, level);
|
||||
}
|
||||
} else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
|
||||
snprintf(attr, sizeof(attr), "mp4a.40.33");
|
||||
} else if (st->codecpar->codec_id == AV_CODEC_ID_MP3) {
|
||||
@ -2247,6 +2291,10 @@ static int hls_write_header(AVFormatContext *s)
|
||||
continue;
|
||||
}
|
||||
avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
|
||||
if (outer_st->codecpar->codec_id == AV_CODEC_ID_HEVC &&
|
||||
outer_st->codecpar->codec_tag != MKTAG('h','v','c','1')) {
|
||||
av_log(s, AV_LOG_WARNING, "Stream HEVC is not hvc1, you should use tag:v hvc1 to set it.\n");
|
||||
}
|
||||
write_codec_attr(outer_st, vs);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user