Ticket #6243: H264Parser-fixes-v1.1.patch

File H264Parser-fixes-v1.1.patch, 12.2 KB (added by jppoet@…, 3 years ago)

Allows recorder to designate if I frames should be counted as keyframes

  • libs/libmythtv/mpeg/H264Parser.cpp

    old new  
    33 
    44extern "C" { 
    55// from libavcodec 
    6     extern const uint8_t *ff_find_start_code(const uint8_t * p, const uint8_t *end, uint32_t * state); 
     6    extern const uint8_t *ff_find_start_code(const uint8_t * p, 
     7                                             const uint8_t *end, 
     8                                             uint32_t * state); 
    79#include "avcodec.h" 
    810} 
    911 
    static const float eps = 1E-5; 
    8890H264Parser::H264Parser(void) 
    8991{ 
    9092    Reset(); 
     93    I_is_keyframe = false; 
    9194} 
    9295 
    9396void H264Parser::Reset(void) 
    9497{ 
    9598    state_changed = false; 
    96     seen_sps = seen_IDR = false; 
     99    seen_sps = false; 
     100    is_keyframe = false; 
    97101 
    98102    sync_accumulator = 0xffffffff; 
    99     find_AU = false; 
    100103    AU_pending = false; 
    101104 
    102     NAL_type = UNKNOWN; 
    103  
    104105    frame_num = prev_frame_num = -1; 
    105106    slice_type = SLICE_UNDEF; 
    106107    prev_pic_parameter_set_id = pic_parameter_set_id = -1; 
    void H264Parser::Reset(void) 
    112113    prev_delta_pic_order_cnt_bottom = delta_pic_order_cnt_bottom = 0; 
    113114    prev_delta_pic_order_cnt[0] = delta_pic_order_cnt[0] = 0; 
    114115    prev_delta_pic_order_cnt[1] = delta_pic_order_cnt[1] = 0; 
    115     prev_nal_unit_type = nal_unit_type = 0; 
     116    prev_nal_unit_type = nal_unit_type = UNKNOWN; 
    116117    prev_idr_pic_id = idr_pic_id = 0; 
    117118 
    118119    log2_max_frame_num = log2_max_pic_order_cnt_lsb = 0; 
    void H264Parser::Reset(void) 
    136137 
    137138    AU_offset = frame_start_offset = keyframe_start_offset = 0; 
    138139    on_frame = on_key_frame = false; 
    139  
    140     wait_for_IDR = false; 
    141140} 
    142141 
    143142 
    bool H264Parser::new_AU(void) 
    214213    { 
    215214        // Need previous slice information for comparison 
    216215 
    217         if (NAL_type == AU_DELIMITER || 
    218             NAL_type == SPS || 
    219             NAL_type == PPS || 
    220             NAL_type == SEI || 
    221             (NAL_type > SPS_EXT && NAL_type < AUXILIARY_SLICE)) 
    222             result = true; 
    223         else if (NAL_type != SLICE_IDR && frame_num != prev_frame_num) 
     216        if (nal_unit_type != SLICE_IDR && frame_num != prev_frame_num) 
    224217            result = true; 
    225218        else if (prev_pic_parameter_set_id != -1 && 
    226219                 pic_parameter_set_id != prev_pic_parameter_set_id) 
    bool H264Parser::new_AU(void) 
    230223        else if ((bottom_field_flag != -1 && prev_bottom_field_flag != -1) && 
    231224                 bottom_field_flag != prev_bottom_field_flag) 
    232225            result = true; 
    233         else if ((nal_ref_idc == 0 || prev_nal_ref_idc == 0) && 
    234                  nal_ref_idc != prev_nal_ref_idc) 
    235             result = true; 
    236226        else if ((pic_order_cnt_type == 0 && prev_pic_order_cnt_type == 0) && 
    237227                 (pic_order_cnt_lsb != prev_pic_order_cnt_lsb || 
    238228                  delta_pic_order_cnt_bottom != 
    bool H264Parser::new_AU(void) 
    256246    prev_pic_parameter_set_id = pic_parameter_set_id; 
    257247    prev_field_pic_flag = field_pic_flag; 
    258248    prev_bottom_field_flag = bottom_field_flag; 
    259     prev_nal_ref_idc = nal_ref_idc; 
    260249    prev_pic_order_cnt_lsb = pic_order_cnt_lsb; 
    261250    prev_delta_pic_order_cnt_bottom = delta_pic_order_cnt_bottom; 
    262251    prev_delta_pic_order_cnt[0] = delta_pic_order_cnt[0]; 
    uint32_t H264Parser::addBytes(const uint 
    273262{ 
    274263    const uint8_t *byteP = bytes; 
    275264    const uint8_t *endP = bytes + byte_count; 
    276  
     265    const uint8_t *nalP; 
    277266    uint8_t        first_byte; 
    278267 
    279268    state_changed = false; 
    uint32_t H264Parser::addBytes(const uint 
    305294  11 End of stream end_of_stream_rbsp( ) 
    306295*/ 
    307296            first_byte = *(byteP - 1); 
    308             NAL_type = first_byte & 0x1f; 
     297            nal_unit_type = first_byte & 0x1f; 
    309298            nal_ref_idc = (first_byte >> 5) & 0x3; 
    310299 
    311             if (NALisSlice(NAL_type) || NAL_type == SPS || NAL_type == PPS) 
     300            if (nal_unit_type == SPS || nal_unit_type == PPS || 
     301                nal_unit_type == SEI || NALisSlice(nal_unit_type)) 
    312302            { 
    313303                /* 
    314304                  bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE 
    uint32_t H264Parser::addBytes(const uint 
    318308                { 
    319309                    init_get_bits(&gb, byteP, 8 * (endP - byteP)); 
    320310 
    321                     if (NAL_type == SPS) 
     311                    if (nal_unit_type == SEI) 
     312                    { 
     313                        nalP = ff_find_start_code(byteP+1, endP, 
     314                                                  &sync_accumulator) - 8; 
     315                        decode_SEI(&gb, (nalP - byteP) * 8); 
     316                        set_AU_pending(stream_offset); 
     317                    } 
     318                    else if (nal_unit_type == SPS) 
     319                    { 
    322320                        decode_SPS(&gb); 
    323                     else if (NAL_type == PPS) 
     321                        set_AU_pending(stream_offset); 
     322                    } 
     323                    else if (nal_unit_type == PPS) 
     324                    { 
    324325                        decode_PPS(&gb); 
     326                        set_AU_pending(stream_offset); 
     327                    } 
    325328                    else 
    326                         find_AU = decode_Header(&gb); 
     329                    { 
     330                        decode_Header(&gb); 
     331                        if (new_AU()) 
     332                            set_AU_pending(stream_offset); 
     333                    } 
    327334 
    328335                    byteP += (get_bits_count(&gb) / 8); 
    329336                } 
    330337            } 
    331  
    332             if (find_AU && new_AU()) 
     338            else if (!AU_pending) 
    333339            { 
    334                 /* After finding a new AU, don't look for another one 
    335                    until we decode a SLICE */ 
    336                 find_AU = false; 
    337                 AU_pending = true; 
    338                 AU_offset = stream_offset; 
     340                if (nal_unit_type == AU_DELIMITER || 
     341                    (nal_unit_type > SPS_EXT && 
     342                     nal_unit_type < AUXILIARY_SLICE)) 
     343                { 
     344                    AU_pending = true; 
     345                    AU_offset = stream_offset; 
     346                } 
     347                else if ((nal_ref_idc == 0 || prev_nal_ref_idc == 0) && 
     348                         nal_ref_idc != prev_nal_ref_idc) 
     349                { 
     350                    AU_pending = true; 
     351                    AU_offset = stream_offset; 
     352                } 
    339353            } 
    340              
    341             if (AU_pending && NALisSlice(NAL_type)) 
     354 
     355            if (AU_pending && NALisSlice(nal_unit_type)) 
    342356            { 
    343357                /* Once we know the slice type of a new AU, we can 
    344358                 * determine if it is a keyframe or just a frame */ 
    uint32_t H264Parser::addBytes(const uint 
    349363                on_frame = true; 
    350364                frame_start_offset = AU_offset; 
    351365 
    352                 if (isKeySlice(slice_type) && (!wait_for_IDR || seen_IDR)) 
     366                if (is_keyframe) 
    353367                { 
    354368                    on_key_frame = true; 
    355369                    keyframe_start_offset = AU_offset; 
     370                    is_keyframe = false; 
    356371                } 
    357372                else 
    358373                    on_key_frame = false; 
    uint32_t H264Parser::addBytes(const uint 
    360375            else 
    361376                on_frame = on_key_frame = false; 
    362377 
     378            prev_nal_ref_idc = nal_ref_idc; 
     379 
    363380            return byteP - bytes; 
    364381        } 
    365382    } 
    bool H264Parser::decode_Header(GetBitCon 
    440457    */ 
    441458 
    442459    frame_num = get_bits(gb, log2_max_frame_num); 
    443     if (NAL_type == SLICE_IDR || frame_num == 0) 
    444         seen_IDR = true; 
    445460 
    446461    /* 
    447462      field_pic_flag equal to 1 specifies that the slice is a slice of a 
    bool H264Parser::decode_Header(GetBitCon 
    475490      second such IDR access unit. The value of idr_pic_id shall be in 
    476491      the range of 0 to 65535, inclusive. 
    477492     */ 
     493 
    478494    if (nal_unit_type == SLICE_IDR) 
     495    { 
     496        is_keyframe = true; 
    479497        idr_pic_id = get_ue_golomb(gb); 
     498    } 
     499    else 
     500        is_keyframe |= (I_is_keyframe && isKeySlice(slice_type)); 
    480501 
    481502    /* 
    482503      pic_order_cnt_lsb specifies the picture order count modulo 
    void H264Parser::decode_PPS(GetBitContex 
    806827#endif 
    807828} 
    808829 
     830void H264Parser::decode_SEI(GetBitContext * gb, int bitlen) 
     831{ 
     832    int   recovery_frame_cnt = -1; 
     833    bool  exact_match_flag = false; 
     834    bool  broken_link_flag = false; 
     835    int   changing_group_slice_idc = -1; 
     836 
     837    while (get_bits_count(gb) < bitlen) 
     838    { 
     839        int type = 0, size = 0; 
     840 
     841        do { 
     842            type += show_bits(gb, 8); 
     843        } while (get_bits(gb, 8) == 255); 
     844 
     845        do { 
     846            size += show_bits(gb, 8); 
     847        } while (get_bits(gb, 8) == 255); 
     848 
     849        switch (type) 
     850        { 
     851          case SEI_TYPE_RECOVERY_POINT: 
     852            recovery_frame_cnt = get_ue_golomb(gb); 
     853            exact_match_flag = get_bits1(gb); 
     854            broken_link_flag = get_bits1(gb); 
     855            changing_group_slice_idc = get_bits(gb, 2); 
     856            is_keyframe |= (recovery_frame_cnt >= 0); 
     857            return; 
     858 
     859          default: 
     860            skip_bits(gb, size * 8); 
     861            break; 
     862        } 
     863 
     864        align_get_bits(gb); 
     865    } 
     866} 
     867 
    809868void H264Parser::vui_parameters(GetBitContext * gb) 
    810869{ 
    811870    /* 
  • libs/libmythtv/mpeg/H264Parser.h

    old new class H264Parser { 
    5353        AUXILIARY_SLICE = 19 
    5454    }; 
    5555 
     56    enum SEI_type { 
     57        SEI_TYPE_PIC_TIMING             = 1, 
     58        SEI_TYPE_USER_DATA_UNREGISTERED = 5, 
     59        SEI_TYPE_RECOVERY_POINT         = 6 
     60    }; 
     61 
    5662    /* 
    5763      slice_type values in the range 5..9 specify, in addition to the 
    5864      coding type of the current slice, that all other slices of the 
    class H264Parser { 
    9096 
    9197    bool stateChanged(void) const { return state_changed; } 
    9298 
    93     // seenIDR implies that a SPS has also been seen 
    94     bool seenIDR(void) const { return seen_IDR; } 
    95     uint8_t lastNALtype(void) const { return NAL_type; } 
     99    uint8_t lastNALtype(void) const { return nal_unit_type; } 
    96100 
    97101    frame_type FieldType(void) const 
    98102        { 
    class H264Parser { 
    130134                    nal_type == SLICE_IDR); 
    131135        } 
    132136 
    133     void waitForIDR(bool wait) { wait_for_IDR = wait; } 
     137    void use_I_forKeyframes(bool val) { I_is_keyframe = val; } 
    134138 
    135139  private: 
    136140    enum constants {EXTENDED_SAR = 255}; 
    137141 
    138     bool is_first_VCL_NAL_unit(void); 
     142    inline void set_AU_pending(const uint64_t & stream_offset) 
     143        { 
     144            if (!AU_pending) 
     145            { 
     146                AU_pending = true; 
     147                AU_offset = stream_offset; 
     148            } 
     149        } 
     150 
    139151    bool new_AU(void); 
    140152    bool decode_Header(GetBitContext *gb); 
    141153    void decode_SPS(GetBitContext *gb); 
    142154    void decode_PPS(GetBitContext * gb); 
     155    void decode_SEI(GetBitContext * gb, int len); 
    143156    void vui_parameters(GetBitContext * gb); 
    144157 
    145     bool       find_AU; 
    146158    bool       AU_pending; 
    147159    bool       state_changed; 
    148160    bool       seen_sps; 
    149     bool       seen_IDR; 
     161    bool       is_keyframe; 
     162    bool       I_is_keyframe; 
    150163 
    151164    uint32_t   sync_accumulator; 
    152165    GetBitContext gb; 
    153166 
    154     uint8_t    NAL_type; 
    155  
    156167    int        prev_frame_num, frame_num; 
    157168    uint       slice_type; 
    158169    int        prev_pic_parameter_set_id, pic_parameter_set_id; 
    class H264Parser { 
    188199 
    189200    uint64_t   AU_offset, frame_start_offset, keyframe_start_offset; 
    190201    bool       on_frame, on_key_frame; 
    191  
    192     bool       wait_for_IDR; 
    193202}; 
    194203 
    195204#endif /* H264PARSER_H */ 
  • libs/libmythtv/mpegrecorder.cpp

    old new bool MpegRecorder::OpenV4L2DeviceAsInput 
    423423            bzero(_stream_id,  sizeof(_stream_id)); 
    424424            bzero(_pid_status, sizeof(_pid_status)); 
    425425            memset(_continuity_counter, 0xff, sizeof(_continuity_counter)); 
     426            m_h264_parser.use_I_forKeyframes(true); 
    426427        } 
    427428        else 
    428429        { 
    void MpegRecorder::ResetForNewFile(void) 
    13731374    bzero(_stream_id,  sizeof(_stream_id)); 
    13741375    bzero(_pid_status, sizeof(_pid_status)); 
    13751376    memset(_continuity_counter, 0xff, sizeof(_continuity_counter)); 
    1376  
    1377     m_h264_parser.waitForIDR(true); 
    13781377} 
    13791378 
    13801379void MpegRecorder::Reset(void)