mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-11 08:13:06 +00:00
avcodec/bsf/extract_extradata: write correct length start codes for h26x
The specification for H.26{4,5,6} states that start codes may be three or four
bytes long long except for the first NALU in an AU, and for NALUs of parameter
set types, which must be four bytes long.
This is checked by ff_cbs_h2645_unit_requires_zero_byte(), which is made
available outside of CBS for this change.
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@@ -181,6 +181,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
|
||||
int extradata_size = 0, filtered_size = 0;
|
||||
const int *extradata_nal_types;
|
||||
size_t nb_extradata_nal_types;
|
||||
int filtered_nb_nals = 0;
|
||||
int i, has_sps = 0, has_vps = 0, ret = 0;
|
||||
|
||||
if (ctx->par_in->codec_id == AV_CODEC_ID_VVC) {
|
||||
@@ -202,7 +203,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
|
||||
for (i = 0; i < s->h2645_pkt.nb_nals; i++) {
|
||||
H2645NAL *nal = &s->h2645_pkt.nals[i];
|
||||
if (val_in_array(extradata_nal_types, nb_extradata_nal_types, nal->type)) {
|
||||
extradata_size += nal->raw_size + 3;
|
||||
extradata_size += nal->raw_size + 4;
|
||||
if (ctx->par_in->codec_id == AV_CODEC_ID_VVC) {
|
||||
if (nal->type == VVC_SPS_NUT) has_sps = 1;
|
||||
if (nal->type == VVC_VPS_NUT) has_vps = 1;
|
||||
@@ -213,7 +214,8 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
|
||||
if (nal->type == H264_NAL_SPS) has_sps = 1;
|
||||
}
|
||||
} else if (s->remove) {
|
||||
filtered_size += nal->raw_size + 3;
|
||||
filtered_size += nal->raw_size + 3 +
|
||||
ff_h2645_unit_requires_zero_byte(ctx->par_in->codec_id, nal->type, filtered_nb_nals++);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,13 +248,16 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
|
||||
if (s->remove)
|
||||
bytestream2_init_writer(&pb_filtered_data, filtered_buf->data, filtered_size);
|
||||
|
||||
filtered_nb_nals = 0;
|
||||
for (i = 0; i < s->h2645_pkt.nb_nals; i++) {
|
||||
H2645NAL *nal = &s->h2645_pkt.nals[i];
|
||||
if (val_in_array(extradata_nal_types, nb_extradata_nal_types,
|
||||
nal->type)) {
|
||||
bytestream2_put_be24u(&pb_extradata, 1); //startcode
|
||||
bytestream2_put_be32u(&pb_extradata, 1); //startcode
|
||||
bytestream2_put_bufferu(&pb_extradata, nal->raw_data, nal->raw_size);
|
||||
} else if (s->remove) {
|
||||
if (ff_h2645_unit_requires_zero_byte(ctx->par_in->codec_id, nal->type, filtered_nb_nals++))
|
||||
bytestream2_put_byteu(&pb_filtered_data, 0); // zero_byte
|
||||
bytestream2_put_be24u(&pb_filtered_data, 1); // startcode
|
||||
bytestream2_put_bufferu(&pb_filtered_data, nal->raw_data, nal->raw_size);
|
||||
}
|
||||
|
||||
+1
-19
@@ -320,24 +320,6 @@ int ff_cbs_h2645_write_slice_data(CodedBitstreamContext *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_cbs_h2645_unit_requires_zero_byte(enum AVCodecID codec_id,
|
||||
CodedBitstreamUnitType type,
|
||||
int nal_unit_index)
|
||||
{
|
||||
// Section B.1.2 in H.264, section B.2.2 in H.265, H.266.
|
||||
if (nal_unit_index == 0) {
|
||||
// Assume that this is the first NAL unit in an access unit.
|
||||
return 1;
|
||||
}
|
||||
if (codec_id == AV_CODEC_ID_H264)
|
||||
return type == H264_NAL_SPS || type == H264_NAL_PPS;
|
||||
if (codec_id == AV_CODEC_ID_HEVC)
|
||||
return type == HEVC_NAL_VPS || type == HEVC_NAL_SPS || type == HEVC_NAL_PPS;
|
||||
if (codec_id == AV_CODEC_ID_VVC)
|
||||
return type >= VVC_OPI_NUT && type <= VVC_SUFFIX_APS_NUT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag)
|
||||
{
|
||||
@@ -372,7 +354,7 @@ int ff_cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx,
|
||||
frag->data_bit_padding = unit->data_bit_padding;
|
||||
}
|
||||
|
||||
if (ff_cbs_h2645_unit_requires_zero_byte(ctx->codec->codec_id, unit->type, i)) {
|
||||
if (ff_h2645_unit_requires_zero_byte(ctx->codec->codec_id, unit->type, i)) {
|
||||
// zero_byte
|
||||
data[dp++] = 0;
|
||||
}
|
||||
|
||||
@@ -63,10 +63,6 @@ int ff_cbs_h2645_write_slice_data(CodedBitstreamContext *ctx,
|
||||
struct PutBitContext *pbc, const uint8_t *data,
|
||||
size_t data_size, int data_bit_start);
|
||||
|
||||
int ff_cbs_h2645_unit_requires_zero_byte(enum AVCodecID codec_id,
|
||||
CodedBitstreamUnitType type,
|
||||
int nal_unit_index);
|
||||
|
||||
int ff_cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag);
|
||||
|
||||
|
||||
@@ -664,6 +664,24 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_h2645_unit_requires_zero_byte(enum AVCodecID codec_id,
|
||||
unsigned int type,
|
||||
int nal_unit_index)
|
||||
{
|
||||
// Section B.1.2 in H.264, section B.2.2 in H.265, H.266.
|
||||
if (nal_unit_index == 0) {
|
||||
// Assume that this is the first NAL unit in an access unit.
|
||||
return 1;
|
||||
}
|
||||
if (codec_id == AV_CODEC_ID_H264)
|
||||
return type == H264_NAL_SPS || type == H264_NAL_PPS;
|
||||
if (codec_id == AV_CODEC_ID_HEVC)
|
||||
return type == HEVC_NAL_VPS || type == HEVC_NAL_SPS || type == HEVC_NAL_PPS;
|
||||
if (codec_id == AV_CODEC_ID_VVC)
|
||||
return type >= VVC_OPI_NUT && type <= VVC_SUFFIX_APS_NUT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_h2645_packet_uninit(H2645Packet *pkt)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -123,6 +123,10 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
|
||||
*/
|
||||
void ff_h2645_packet_uninit(H2645Packet *pkt);
|
||||
|
||||
int ff_h2645_unit_requires_zero_byte(enum AVCodecID codec_id,
|
||||
unsigned int type,
|
||||
int nal_unit_index);
|
||||
|
||||
static inline int get_nalsize(int nal_length_size, const uint8_t *buf,
|
||||
int buf_size, int *buf_index, void *logctx)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
0920978f3f8196413c43f0033b55a5b6 *tests/data/fate/copy-trac2211-avi.avi
|
||||
1777956 tests/data/fate/copy-trac2211-avi.avi
|
||||
ab1e2b88e25a8a65b0010ce9dc761f97 *tests/data/fate/copy-trac2211-avi.avi
|
||||
1777958 tests/data/fate/copy-trac2211-avi.avi
|
||||
#tb 0: 1/14
|
||||
#media_type 0: video
|
||||
#codec_id 0: rawvideo
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
b6ff5910928ad0b2a7eec481dcc41594 *tests/data/fate/h264_mp4toannexb_ticket2991.h264
|
||||
1985815 tests/data/fate/h264_mp4toannexb_ticket2991.h264
|
||||
#extradata 0: 47, 0x3a590d55
|
||||
#extradata 0: 49, 0x459b0d55
|
||||
#tb 0: 1/1200000
|
||||
#media_type 0: video
|
||||
#codec_id 0: h264
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
edddeef7901b2bd8d55625b8105b579f *tests/data/fate/h264_mp4toannexb_ticket5927.h264
|
||||
595583 tests/data/fate/h264_mp4toannexb_ticket5927.h264
|
||||
#extradata 0: 33, 0x84e308f7
|
||||
#extradata 0: 35, 0x8c0208f7
|
||||
#tb 0: 1/1200000
|
||||
#media_type 0: video
|
||||
#codec_id 0: h264
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
edddeef7901b2bd8d55625b8105b579f *tests/data/fate/h264_mp4toannexb_ticket5927_2.h264
|
||||
595583 tests/data/fate/h264_mp4toannexb_ticket5927_2.h264
|
||||
#extradata 0: 33, 0x84e308f7
|
||||
#extradata 0: 35, 0x8c0208f7
|
||||
#tb 0: 1/1200000
|
||||
#media_type 0: video
|
||||
#codec_id 0: h264
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#extradata 0: 88, 0x61e61071
|
||||
#extradata 0: 91, 0x721f1071
|
||||
#tb 0: 1/1000
|
||||
#media_type 0: video
|
||||
#codec_id 0: hevc
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#extradata 0: 50, 0x4f1b0df9
|
||||
#extradata 0: 52, 0x5a8b0df9
|
||||
#tb 0: 1/90000
|
||||
#media_type 0: video
|
||||
#codec_id 0: h264
|
||||
|
||||
@@ -72,5 +72,5 @@ packet|codec_type=video|stream_index=0|pts=546000|pts_time=6.066667|dts=546000|d
|
||||
packet|codec_type=video|stream_index=0|pts=552000|pts_time=6.133333|dts=552000|dts_time=6.133333|duration=6000|duration_time=0.066667|size=16|pos=15604|flags=___|data_hash=CRC32:cca62b67|side_datum/mpegts_stream_id:side_data_type=MPEGTS Stream ID|side_datum/mpegts_stream_id:id=224
|
||||
packet|codec_type=video|stream_index=0|pts=558000|pts_time=6.200000|dts=558000|dts_time=6.200000|duration=6000|duration_time=0.066667|size=16|pos=15792|flags=___|data_hash=CRC32:27b943ef|side_datum/mpegts_stream_id:side_data_type=MPEGTS Stream ID|side_datum/mpegts_stream_id:id=224
|
||||
packet|codec_type=video|stream_index=0|pts=564000|pts_time=6.266667|dts=564000|dts_time=6.266667|duration=6000|duration_time=0.066667|size=16|pos=16356|flags=___|data_hash=CRC32:f7116111|side_datum/mpegts_stream_id:side_data_type=MPEGTS Stream ID|side_datum/mpegts_stream_id:id=224
|
||||
stream|index=0|codec_name=h264|profile=578|codec_type=video|codec_tag_string=[27][0][0][0]|codec_tag=0x001b|mime_codec_string=avc1.42c00a|width=82|height=144|coded_width=82|coded_height=144|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=41:72|pix_fmt=yuv420p|level=10|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=left|field_order=progressive|is_avc=false|nal_length_size=0|ts_id=1|ts_packetsize=188|id=0x100|r_frame_rate=15/1|avg_frame_rate=15/1|time_base=1/90000|start_pts=126000|start_time=1.400000|duration_ts=444000|duration=4.933333|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=8|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=74|extradata_size=35|extradata_hash=CRC32:e62cae27|disposition:default=0|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:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0
|
||||
stream|index=0|codec_name=h264|profile=578|codec_type=video|codec_tag_string=[27][0][0][0]|codec_tag=0x001b|mime_codec_string=avc1.42c00a|width=82|height=144|coded_width=82|coded_height=144|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=41:72|pix_fmt=yuv420p|level=10|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=left|field_order=progressive|is_avc=false|nal_length_size=0|ts_id=1|ts_packetsize=188|id=0x100|r_frame_rate=15/1|avg_frame_rate=15/1|time_base=1/90000|start_pts=126000|start_time=1.400000|duration_ts=444000|duration=4.933333|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=8|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=74|extradata_size=37|extradata_hash=CRC32:1d7ffe93|disposition:default=0|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:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0
|
||||
format|filename=h264small.ts|nb_streams=1|nb_programs=1|nb_stream_groups=0|format_name=mpegts|start_time=1.400000|duration=4.933333|size=16544|bit_rate=26828|probe_score=50
|
||||
|
||||
Reference in New Issue
Block a user