[FFmpeg-devel] [PATCH] h264: Add Intra and Constrained Baseline profiles to avctx.profile
Janne Grunau
janne-ffmpeg
Sat Jan 29 19:43:02 CET 2011
previous patch missed the same same code to compute the level in
h264_parser.c. factored to a function. I've checked against some conformance
bitstreams and all matched the annotations.
Janne
---8<---
---
libavcodec/avcodec.h | 23 +++++++++++++++--------
libavcodec/h264.c | 29 ++++++++++++++++++++++++++++-
libavcodec/h264.h | 6 ++++++
libavcodec/h264_parser.c | 2 +-
libavcodec/h264_ps.c | 11 ++++++-----
5 files changed, 56 insertions(+), 15 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 601f8ed..d0de610 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2260,14 +2260,21 @@ typedef struct AVCodecContext {
#define FF_PROFILE_DTS_HD_HRA 50
#define FF_PROFILE_DTS_HD_MA 60
-#define FF_PROFILE_H264_BASELINE 66
-#define FF_PROFILE_H264_MAIN 77
-#define FF_PROFILE_H264_EXTENDED 88
-#define FF_PROFILE_H264_HIGH 100
-#define FF_PROFILE_H264_HIGH_10 110
-#define FF_PROFILE_H264_HIGH_422 122
-#define FF_PROFILE_H264_HIGH_444 244
-#define FF_PROFILE_H264_CAVLC_444 44
+#define FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag
+#define FF_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag
+
+#define FF_PROFILE_H264_BASELINE 66
+#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
+#define FF_PROFILE_H264_MAIN 77
+#define FF_PROFILE_H264_EXTENDED 88
+#define FF_PROFILE_H264_HIGH 100
+#define FF_PROFILE_H264_HIGH_10 110
+#define FF_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA)
+#define FF_PROFILE_H264_HIGH_422 122
+#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA)
+#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244
+#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA)
+#define FF_PROFILE_H264_CAVLC_444 44
/**
* level
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 2a3357b..774e97d 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -1678,6 +1678,33 @@ static void clone_slice(H264Context *dst, H264Context *src)
}
/**
+ * computes profile from profile_idc and constraint_set?_flags
+ *
+ * @param sps SPS
+ *
+ * @return profile as defined by FF_PROFILE_H264_*
+ */
+int ff_h264_get_profile(SPS *sps)
+{
+ int profile = sps->profile_idc;
+
+ switch(sps->profile_idc) {
+ case FF_PROFILE_H264_BASELINE:
+ // constraint_set1_flag set to 1
+ profile |= (sps->constraint_set_flags & 1<<1) ? FF_PROFILE_H264_CONSTRAINED : 0;
+ break;
+ case FF_PROFILE_H264_HIGH_10:
+ case FF_PROFILE_H264_HIGH_422:
+ case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
+ // constraint_set3_flag set to 1
+ profile |= (sps->constraint_set_flags & 1<<3) ? FF_PROFILE_H264_INTRA : 0;
+ break;
+ }
+
+ return profile;
+}
+
+/**
* decodes a slice header.
* This will also call MPV_common_init() and frame_start() as needed.
*
@@ -1756,7 +1783,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
}
h->sps = *h0->sps_buffers[h->pps.sps_id];
- s->avctx->profile = h->sps.profile_idc;
+ s->avctx->profile = ff_h264_get_profile(&h->sps);
s->avctx->level = h->sps.level_idc;
s->avctx->refs = h->sps.ref_frame_count;
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index f4f9b25..b403968 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -209,6 +209,7 @@ typedef struct SPS{
int bit_depth_luma; ///< bit_depth_luma_minus8 + 8
int bit_depth_chroma; ///< bit_depth_chroma_minus8 + 8
int residual_color_transform_flag; ///< residual_colour_transform_flag
+ int constraint_set_flags; ///< constraint_set[0-3]_flag
}SPS;
/**
@@ -612,6 +613,11 @@ int ff_h264_decode_sei(H264Context *h);
int ff_h264_decode_seq_parameter_set(H264Context *h);
/**
+ * compute profile from sps
+ */
+int ff_h264_get_profile(SPS *sps);
+
+/**
* Decode PPS
*/
int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length);
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 51760dc..c5728e2 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -187,7 +187,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
h->sps = *h->sps_buffers[h->pps.sps_id];
h->frame_num = get_bits(&h->s.gb, h->sps.log2_max_frame_num);
- avctx->profile = h->sps.profile_idc;
+ avctx->profile = ff_h264_get_profile(&h->sps);
avctx->level = h->sps.level_idc;
if(h->sps.frame_mbs_only_flag){
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index 876bcb2..3fe5815 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -267,16 +267,16 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s
int ff_h264_decode_seq_parameter_set(H264Context *h){
MpegEncContext * const s = &h->s;
- int profile_idc, level_idc;
+ int profile_idc, level_idc, constraint_set_flags = 0;
unsigned int sps_id;
int i;
SPS *sps;
profile_idc= get_bits(&s->gb, 8);
- get_bits1(&s->gb); //constraint_set0_flag
- get_bits1(&s->gb); //constraint_set1_flag
- get_bits1(&s->gb); //constraint_set2_flag
- get_bits1(&s->gb); //constraint_set3_flag
+ constraint_set_flags |= get_bits1(&s->gb) << 0; //constraint_set0_flag
+ constraint_set_flags |= get_bits1(&s->gb) << 1; //constraint_set1_flag
+ constraint_set_flags |= get_bits1(&s->gb) << 2; //constraint_set2_flag
+ constraint_set_flags |= get_bits1(&s->gb) << 3; //constraint_set3_flag
get_bits(&s->gb, 4); // reserved
level_idc= get_bits(&s->gb, 8);
sps_id= get_ue_golomb_31(&s->gb);
@@ -291,6 +291,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
sps->time_offset_length = 24;
sps->profile_idc= profile_idc;
+ sps->constraint_set_flags = constraint_set_flags;
sps->level_idc= level_idc;
memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
--
1.7.4.rc2
More information about the ffmpeg-devel
mailing list