aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMickaƫl Raulet <mraulet@insa-rennes.fr>2013-10-30 12:28:19 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-10-31 10:00:22 +0100
commit7c8b65f688ea75496e278b7c042f2eda746f3eac (patch)
treeef99499ade9ade6e460b865301944648d6b725d5
parent6c4b87d3d6ae08a6da16b4616626b4d2a726afbf (diff)
downloadffmpeg-7c8b65f688ea75496e278b7c042f2eda746f3eac.tar.gz
hevc: add partial support for interlaced(cherry picked from commit 44b592ae6d323445c076ef3ec966ebf9daa8bccf)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/hevc.c1
-rw-r--r--libavcodec/hevc.h3
-rw-r--r--libavcodec/hevc_parser.c2
-rw-r--r--libavcodec/hevc_refs.c2
-rw-r--r--libavcodec/hevc_sei.c74
5 files changed, 73 insertions, 9 deletions
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index aaf319f522..9528323992 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -2834,6 +2834,7 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx)
return ret;
s->enable_parallel_tiles = 0;
+ s->picture_struct = 0;
if(avctx->active_thread_type & FF_THREAD_SLICE)
s->threads_number = avctx->thread_count;
diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index 4b45323bb3..df80475703 100644
--- a/libavcodec/hevc.h
+++ b/libavcodec/hevc.h
@@ -869,9 +869,12 @@ typedef struct HEVCContext {
///< as a format defined in 14496-15
int strict_def_disp_win;
+ int active_seq_parameter_set_id;
+
int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4)
int nuh_layer_id;
+ int picture_struct;
} HEVCContext;
int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,
diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
index 642f9752a4..aacf3431dc 100644
--- a/libavcodec/hevc_parser.c
+++ b/libavcodec/hevc_parser.c
@@ -165,6 +165,8 @@ static inline int parse_nal_units(AVCodecParserContext *s,
case NAL_IDR_N_LP:
case NAL_CRA_NUT:
sh->first_slice_in_pic_flag = get_bits1(gb);
+ s->picture_structure = h->picture_struct;
+ s->field_order = h->picture_struct;
if (h->nal_unit_type >= 16 && h->nal_unit_type <= 23) {
s->key_frame = 1;
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index 6bdd37edda..bf3d953d1f 100644
--- a/libavcodec/hevc_refs.c
+++ b/libavcodec/hevc_refs.c
@@ -106,6 +106,8 @@ static HEVCFrame *alloc_frame(HEVCContext *s)
for (j = 0; j < frame->ctb_count; j++)
frame->rpl_tab[j] = (RefPicListTab*)frame->rpl_buf->data;
+ frame->frame->top_field_first = s->picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD;
+ frame->frame->interlaced_frame = (s->picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || (s->picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD);
return frame;
fail:
ff_hevc_unref_frame(s, frame, ~0);
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 1a964477de..5c404a3cdc 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -51,9 +51,9 @@ static void decode_nal_sei_decoded_picture_hash(HEVCContext *s, int payload_size
}
}
-static void decode_nal_sei_frame_packing_arrangement(HEVCLocalContext *lc)
+static void decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
{
- GetBitContext *gb = &lc->gb;
+ GetBitContext *gb = &s->HEVClc->gb;
int cancel, type, quincunx;
get_ue_golomb(gb); // frame_packing_arrangement_id
@@ -77,6 +77,46 @@ static void decode_nal_sei_frame_packing_arrangement(HEVCLocalContext *lc)
skip_bits1(gb); // upsampled_aspect_ratio_flag
}
+static int decode_pic_timing(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ HEVCSPS *sps = (HEVCSPS*)s->sps_list[s->active_seq_parameter_set_id]->data;
+
+ if (!sps)
+ return(AVERROR(ENOMEM));
+
+ if (sps->vui.frame_field_info_present_flag) {
+ int pic_struct = get_bits(gb, 4);
+ s->picture_struct = AV_PICTURE_STRUCTURE_UNKNOWN;
+ if (pic_struct == 2) {
+ av_log(s->avctx, AV_LOG_DEBUG, "BOTTOM Field\n");
+ s->picture_struct = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
+ } else if (pic_struct == 1) {
+ av_log(s->avctx, AV_LOG_DEBUG, "TOP Field\n");
+ s->picture_struct = AV_PICTURE_STRUCTURE_TOP_FIELD;
+ }
+ get_bits(gb, 2); // source_scan_type
+ get_bits(gb, 1); // duplicate_flag
+ }
+ return 1;
+}
+
+static void active_parameter_sets(HEVCContext *s) {
+ GetBitContext *gb = &s->HEVClc->gb;
+ int num_sps_ids_minus1;
+ int i;
+
+ get_bits(gb, 4); // active_video_parameter_set_id
+ get_bits(gb, 1); // self_contained_cvs_flag
+ get_bits(gb, 1); // num_sps_ids_minus1
+ num_sps_ids_minus1 = get_ue_golomb_long(gb); // num_sps_ids_minus1
+
+ s->active_seq_parameter_set_id = get_ue_golomb_long(gb);
+
+ for (i = 1; i <= num_sps_ids_minus1; i++)
+ get_ue_golomb_long(gb); // active_seq_parameter_set_id[i]
+}
+
static int decode_nal_sei_message(HEVCContext *s)
{
GetBitContext *gb = &s->HEVClc->gb;
@@ -96,13 +136,25 @@ static int decode_nal_sei_message(HEVCContext *s)
payload_size += byte;
}
if (s->nal_unit_type == NAL_SEI_PREFIX) {
- if (payload_type == 256 /*&& s->decode_checksum_sei*/)
+ if (payload_type == 256 /*&& s->decode_checksum_sei*/) {
decode_nal_sei_decoded_picture_hash(s, payload_size);
- else if (payload_type == 45)
- decode_nal_sei_frame_packing_arrangement(s->HEVClc);
- else {
+ return 1;
+ } else if (payload_type == 45) {
+ decode_nal_sei_frame_packing_arrangement(s);
+ return 1;
+ } else if (payload_type == 1){
+ int ret = decode_pic_timing(s);
av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type);
skip_bits(gb, 8*payload_size);
+ return ret;
+ } else if (payload_type == 129){
+ active_parameter_sets(s);
+ av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type);
+ return 1;
+ } else {
+ av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type);
+ skip_bits(gb, 8*payload_size);
+ return 1;
}
} else { /* nal_unit_type == NAL_SEI_SUFFIX */
if (payload_type == 132 /* && s->decode_checksum_sei */)
@@ -111,8 +163,8 @@ static int decode_nal_sei_message(HEVCContext *s)
av_log(s->avctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", payload_type);
skip_bits(gb, 8*payload_size);
}
+ return 1;
}
- return 0;
}
static int more_rbsp_data(GetBitContext *gb)
@@ -122,8 +174,12 @@ static int more_rbsp_data(GetBitContext *gb)
int ff_hevc_decode_nal_sei(HEVCContext *s)
{
+ int ret;
+
do {
- decode_nal_sei_message(s);
+ ret = decode_nal_sei_message(s);
+ if (ret < 0)
+ return(AVERROR(ENOMEM));
} while (more_rbsp_data(&s->HEVClc->gb));
- return 0;
+ return 1;
}