diff options
author | Mickaƫl Raulet <mraulet@insa-rennes.fr> | 2013-10-30 12:28:19 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-10-31 10:00:22 +0100 |
commit | 7c8b65f688ea75496e278b7c042f2eda746f3eac (patch) | |
tree | ef99499ade9ade6e460b865301944648d6b725d5 | |
parent | 6c4b87d3d6ae08a6da16b4616626b4d2a726afbf (diff) | |
download | ffmpeg-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.c | 1 | ||||
-rw-r--r-- | libavcodec/hevc.h | 3 | ||||
-rw-r--r-- | libavcodec/hevc_parser.c | 2 | ||||
-rw-r--r-- | libavcodec/hevc_refs.c | 2 | ||||
-rw-r--r-- | libavcodec/hevc_sei.c | 74 |
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; } |