Message ID | 20201012091813.55564-1-lq@chinaffmpeg.org |
---|---|
State | Superseded |
Headers | show |
Series | [FFmpeg-devel] avformat/hlsenc: support CODECS Attribute in hevc EXT-X-STREAM-INF | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
andriy/PPC64_make | warning | Make failed |
On Mon, Oct 12, 2020 at 5:18 PM Steven Liu <lq@chinaffmpeg.org> wrote: > fix ticket: 8904 > parse the SPS from extradata and get profile_tier_level > write the profile_tier_level info into 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> > --- > libavformat/hlsenc.c | 41 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 41 insertions(+) > > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c > index cb31d6aed7..574d9f81e9 100644 > --- a/libavformat/hlsenc.c > +++ b/libavformat/hlsenc.c > @@ -337,6 +337,43 @@ 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 i = 0; > + 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; > + > + while (data && (data - st->codecpar->extradata) < > st->codecpar->extradata_size) { > + /* get HEVC SPS NAL and seek to profile_tier_level */ > + if (data && (data[0] | data[1] | data[2]) == 0 && data[3] == > 1 && ((data[4] & 0x42) == 0x42)) { > Read beyond the boundary if data + 1 - st->codecpar->extradata >= st->codecpar->extradata_size Is it possible reuese ff_hevc_decode_extradata here? + int rbsp_byte_size; > + data += 7; > + /* process by reference General NAL unit syntax */ > + profile = *data & 0x1f; > + rbsp_byte_size = st->codecpar->extradata_size - (data - > st->codecpar->extradata); > + for (i = 0; i < rbsp_byte_size; i++, data++) { > + if (data[0] == 0 && data[1] == 0 && data[2] == 3) { > + data += 2; > + i++; > + } > + /* skip 8 + 32 + 4 + 43 + 1 bit */ > + if (i == 11) > + level = *data; > + } > + 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 +2284,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); > > } > -- > 2.25.0 > > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> 在 2020年10月12日,21:45,Guangxin Xu <oddstone@gmail.com> 写道: > > > > On Mon, Oct 12, 2020 at 5:18 PM Steven Liu <lq@chinaffmpeg.org> wrote: > fix ticket: 8904 > parse the SPS from extradata and get profile_tier_level > write the profile_tier_level info into 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> > --- > libavformat/hlsenc.c | 41 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 41 insertions(+) > > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c > index cb31d6aed7..574d9f81e9 100644 > --- a/libavformat/hlsenc.c > +++ b/libavformat/hlsenc.c > @@ -337,6 +337,43 @@ 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 i = 0; > + 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; > + > + while (data && (data - st->codecpar->extradata) < st->codecpar->extradata_size) { > + /* get HEVC SPS NAL and seek to profile_tier_level */ > + if (data && (data[0] | data[1] | data[2]) == 0 && data[3] == 1 && ((data[4] & 0x42) == 0x42)) { > Read beyond the boundary if data + 1 - st->codecpar->extradata >= st->codecpar->extradata_size ok > Is it possible reuese ff_hevc_decode_extradata here? it is in libavcodec, i don’t think depend libavcodec in hlsenc is a good way, so parse sps here. > > + int rbsp_byte_size; > + data += 7; > + /* process by reference General NAL unit syntax */ > + profile = *data & 0x1f; > + rbsp_byte_size = st->codecpar->extradata_size - (data - st->codecpar->extradata); > + for (i = 0; i < rbsp_byte_size; i++, data++) { > + if (data[0] == 0 && data[1] == 0 && data[2] == 3) { > + data += 2; > + i++; > + } > + /* skip 8 + 32 + 4 + 43 + 1 bit */ > + if (i == 11) > + level = *data; > + } > + 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 +2284,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); > > } > -- > 2.25.0 > > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". Thanks Steven
On Mon, Oct 12, 2020 at 9:57 PM Steven Liu <lq@chinaffmpeg.org> wrote: > > > > 在 2020年10月12日,21:45,Guangxin Xu <oddstone@gmail.com> 写道: > > > > > > > > On Mon, Oct 12, 2020 at 5:18 PM Steven Liu <lq@chinaffmpeg.org> wrote: > > fix ticket: 8904 > > parse the SPS from extradata and get profile_tier_level > > write the profile_tier_level info into 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> > > --- > > libavformat/hlsenc.c | 41 +++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 41 insertions(+) > > > > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c > > index cb31d6aed7..574d9f81e9 100644 > > --- a/libavformat/hlsenc.c > > +++ b/libavformat/hlsenc.c > > @@ -337,6 +337,43 @@ 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 i = 0; > > + 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; > > + > > + while (data && (data - st->codecpar->extradata) < > st->codecpar->extradata_size) { > > + /* get HEVC SPS NAL and seek to profile_tier_level */ > > + if (data && (data[0] | data[1] | data[2]) == 0 && data[3] > == 1 && ((data[4] & 0x42) == 0x42)) { > > Read beyond the boundary if data + 1 - st->codecpar->extradata >= > st->codecpar->extradata_size > ok > > Is it possible reuese ff_hevc_decode_extradata here? > it is in libavcodec, i don’t think depend libavcodec in hlsenc is a good > way, so parse sps here. > Then, we have a lot of hard work: 1. remove emulation prevent code. 2. get profile/level from vps too. full details you can check at https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/hevc.c#L713 thanks > > > > + int rbsp_byte_size; > > + data += 7; > > + /* process by reference General NAL unit syntax */ > > + profile = *data & 0x1f; > > + rbsp_byte_size = st->codecpar->extradata_size - (data - > st->codecpar->extradata); > > + for (i = 0; i < rbsp_byte_size; i++, data++) { > > + if (data[0] == 0 && data[1] == 0 && data[2] == 3) { > > + data += 2; > > + i++; > > + } > > + /* skip 8 + 32 + 4 + 43 + 1 bit */ > > + if (i == 11) > > + level = *data; > > + } > > + 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 +2284,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); > > > > } > > -- > > 2.25.0 > > > > > > > > _______________________________________________ > > ffmpeg-devel mailing list > > ffmpeg-devel@ffmpeg.org > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > To unsubscribe, visit link above, or email > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > Thanks > Steven > > > > > > >
> 2020年10月12日 下午11:43,Guangxin Xu <oddstone@gmail.com> 写道: > > On Mon, Oct 12, 2020 at 9:57 PM Steven Liu <lq@chinaffmpeg.org> wrote: > >> >> >>> 在 2020年10月12日,21:45,Guangxin Xu <oddstone@gmail.com> 写道: >>> >>> >>> >>> On Mon, Oct 12, 2020 at 5:18 PM Steven Liu <lq@chinaffmpeg.org> wrote: >>> fix ticket: 8904 >>> parse the SPS from extradata and get profile_tier_level >>> write the profile_tier_level info into 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> >>> --- >>> libavformat/hlsenc.c | 41 +++++++++++++++++++++++++++++++++++++++++ >>> 1 file changed, 41 insertions(+) >>> >>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c >>> index cb31d6aed7..574d9f81e9 100644 >>> --- a/libavformat/hlsenc.c >>> +++ b/libavformat/hlsenc.c >>> @@ -337,6 +337,43 @@ 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 i = 0; >>> + 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; >>> + >>> + while (data && (data - st->codecpar->extradata) < >> st->codecpar->extradata_size) { >>> + /* get HEVC SPS NAL and seek to profile_tier_level */ >>> + if (data && (data[0] | data[1] | data[2]) == 0 && data[3] >> == 1 && ((data[4] & 0x42) == 0x42)) { >>> Read beyond the boundary if data + 1 - st->codecpar->extradata >= >> st->codecpar->extradata_size >> ok >>> Is it possible reuese ff_hevc_decode_extradata here? >> it is in libavcodec, i don’t think depend libavcodec in hlsenc is a good >> way, so parse sps here. >> > Then, we have a lot of hard work: > 1. remove emulation prevent code. > 2. get profile/level from vps too. Do you mean it must or always show in VPS? I think it should alway in SPS if I’m not misunderstand. > full details you can check at > https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/hevc.c#L713 I just want get profile, tier and level in hlsenc, At first I parse the nalunit as the libavformat/hevc, but I think hlsenc maybe not need alloc new memory to save the new extract_rbsp, just get the value is ok here. So I think just check the boundary is ok here, isn’t it? > > thanks > > > >>> >>> + int rbsp_byte_size; >>> + data += 7; >>> + /* process by reference General NAL unit syntax */ >>> + profile = *data & 0x1f; >>> + rbsp_byte_size = st->codecpar->extradata_size - (data - >> st->codecpar->extradata); >>> + for (i = 0; i < rbsp_byte_size; i++, data++) { >>> + if (data[0] == 0 && data[1] == 0 && data[2] == 3) { >>> + data += 2; >>> + i++; >>> + } >>> + /* skip 8 + 32 + 4 + 43 + 1 bit */ >>> + if (i == 11) >>> + level = *data; >>> + } >>> + 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 +2284,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); >>> >>> } >>> -- >>> 2.25.0 >>> >>> >>> >>> _______________________________________________ >>> ffmpeg-devel mailing list >>> ffmpeg-devel@ffmpeg.org >>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >>> >>> To unsubscribe, visit link above, or email >>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> >> Thanks >> Steven >> >> >> >> >> >> >> > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". Thanks Steven Liu
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index cb31d6aed7..574d9f81e9 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -337,6 +337,43 @@ 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 i = 0; + 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; + + while (data && (data - st->codecpar->extradata) < st->codecpar->extradata_size) { + /* get HEVC SPS NAL and seek to profile_tier_level */ + if (data && (data[0] | data[1] | data[2]) == 0 && data[3] == 1 && ((data[4] & 0x42) == 0x42)) { + int rbsp_byte_size; + data += 7; + /* process by reference General NAL unit syntax */ + profile = *data & 0x1f; + rbsp_byte_size = st->codecpar->extradata_size - (data - st->codecpar->extradata); + for (i = 0; i < rbsp_byte_size; i++, data++) { + if (data[0] == 0 && data[1] == 0 && data[2] == 3) { + data += 2; + i++; + } + /* skip 8 + 32 + 4 + 43 + 1 bit */ + if (i == 11) + level = *data; + } + 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 +2284,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); }
fix ticket: 8904 parse the SPS from extradata and get profile_tier_level write the profile_tier_level info into 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> --- libavformat/hlsenc.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)