Ticket #4752: h264_length.diff

File h264_length.diff, 7.6 KB (added by anonymous, 3 years ago)

Prevent double-length recordings on STABLE

  • libs/libmythtv/mpeg/h264utils.cpp

    old new  
    4242extern "C" { 
    4343// from libavcodec 
    4444extern const uint8_t *ff_find_start_code(const uint8_t * p, const uint8_t *end, uint32_t * state); 
     45#include "avcodec.h" 
    4546} 
    4647 
    4748namespace H264 
     
    6263 
    6364    first_NAL_byte = H264::NALUnitType::UNKNOWN; 
    6465 
     66    log2_max_frame_num = -1; 
     67    frame_num = 0; 
     68    prev_frame_num = -1; 
     69 
    6570    saw_AU_delimiter = false; 
    6671    saw_first_VCL_NAL_unit = false; 
    6772    saw_sps = false; 
     73    separate_colour_plane_flag = false; 
     74    frame_mbs_only_flag = true; 
     75    new_VLC_NAL = false; 
    6876 
    6977    did_evaluate_once = false; 
    7078    keyframe = false; 
     
    127135    // stage 3: did we see the AU's first VCL NAL unit yet? 
    128136    if (!saw_first_VCL_NAL_unit && NALUnitType::IsVCLType(new_NAL_type)) 
    129137    { 
    130         saw_first_VCL_NAL_unit = true; 
     138        saw_first_VCL_NAL_unit = new_VLC_NAL; 
    131139        saw_AU_delimiter = false; 
    132140        state_changed = true; 
    133141        if (saw_sps) 
     
    154162        if ((sync_accumulator & 0xffffff00) == 0x00000100) 
    155163        { 
    156164            uint8_t k = *(local_bytes-1); 
     165            uint8_t NAL_type = k & 0x1f; 
    157166            sync_stream_offset = stream_offset; 
    158167            keyframe = false; 
    159168 
     169            if (NAL_type == NALUnitType::SPS || 
     170                NAL_type == NALUnitType::SLICE || 
     171                NAL_type == NALUnitType::SLICE_DPA) { 
     172            /* 
     173              bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE 
     174              bytes larger then the actual read bits 
     175            */ 
     176                if (local_bytes + 20 + FF_INPUT_BUFFER_PADDING_SIZE < 
     177                    local_bytes_end) { 
     178                    init_get_bits(&gb, local_bytes, 
     179                                  8 * (local_bytes_end - local_bytes)); 
     180 
     181                    if (NAL_type == NALUnitType::SPS) 
     182                        decode_SPS(&gb); 
     183                    else 
     184                        decode_Header(&gb); 
     185                } 
     186 
     187            } 
     188            else if (NAL_type == NALUnitType::SLICE_IDR) 
     189                frame_num = 0; 
     190 
    160191            KeyframePredicate(k); 
    161192            first_NAL_byte = k; 
    162193 
     
    175206    return saw_first_VCL_NAL_unit; 
    176207} 
    177208 
     209void KeyframeSequencer::decode_Header(GetBitContext * gb) 
     210{ 
     211    uint       first_mb_in_slice; 
     212    uint       slice_type; 
     213    uint       pic_parameter_set_id; 
     214    bool       field_pic_flag; 
     215    bool       bottom_field_flag; 
     216 
     217    if (log2_max_frame_num < 1) 
     218    { 
     219        std::cerr 
     220            << "KeyframeSequencer::decode_Header: SPS has not been parsed!\n"; 
     221        return; 
     222    } 
     223 
     224    new_VLC_NAL = false; 
     225 
     226    prev_frame_num = frame_num; 
     227 
     228    first_mb_in_slice = get_ue_golomb(gb); 
     229    slice_type = get_ue_golomb(gb); 
     230 
     231    pic_parameter_set_id = get_ue_golomb(gb); 
     232    if (pic_parameter_set_id != prev_pic_parameter_set_id) { 
     233        new_VLC_NAL = true; 
     234        prev_pic_parameter_set_id = pic_parameter_set_id; 
     235    } 
     236 
     237    if (separate_colour_plane_flag) 
     238        get_bits(gb, 2);  // colour_plane_id 
     239 
     240    frame_num = get_bits(gb, log2_max_frame_num); 
     241 
     242    if (frame_mbs_only_flag) 
     243        new_VLC_NAL = true; 
     244    else 
     245    { 
     246        /* From section 7.3.3 Slice header syntax 
     247          if (!frame_mbs_only_flag) { 
     248            field_pic_flag = get_bits1(gb); 
     249            if (field_pic_flag) 
     250              bottom_field_flag = get_bits1(gb); 
     251          } 
     252         */ 
     253 
     254#if 0 
     255        new_VLC_NAL = get_bits1(gb) ? !get_bits1(gb) : true; 
     256#else 
     257        field_pic_flag = get_bits1(gb); 
     258        if (field_pic_flag != prev_field_pic_flag) { 
     259            new_VLC_NAL = true; 
     260            prev_field_pic_flag = field_pic_flag; 
     261        } 
     262 
     263        if (field_pic_flag) { 
     264            bottom_field_flag = get_bits1(gb); 
     265            if (bottom_field_flag != prev_bottom_field_flag) { 
     266                new_VLC_NAL = !bottom_field_flag; 
     267                prev_bottom_field_flag = bottom_field_flag; 
     268            } 
     269        } 
     270#endif 
     271    } 
     272} 
     273 
     274/* 
     275 * libavcodec used for example 
     276 */ 
     277void KeyframeSequencer::decode_SPS(GetBitContext * gb) 
     278{ 
     279    int profile_idc, chroma_format_idc; 
     280 
     281    profile_idc = get_bits(gb, 8); // profile_idc 
     282    get_bits1(gb);   // constraint_set0_flag 
     283    get_bits1(gb);   // constraint_set1_flag 
     284    get_bits1(gb);   // constraint_set2_flag 
     285    get_bits1(gb);   // constraint_set3_flag 
     286    get_bits(gb, 4); // reserved 
     287    get_bits(gb, 8); // level_idc 
     288    get_ue_golomb(gb);  // sps_id 
     289 
     290    if(profile_idc >= 100){ // high profile 
     291        if((chroma_format_idc = get_ue_golomb(gb)) == 3) // chroma_format_idc 
     292            separate_colour_plane_flag = (get_bits1(gb) == 1); 
     293        get_ue_golomb(gb);  // bit_depth_luma_minus8 
     294        get_ue_golomb(gb);  // bit_depth_chroma_minus8 
     295        get_bits1(gb);      // qpprime_y_zero_transform_bypass_flag 
     296 
     297        if (get_bits1(gb))      // seq_scaling_matrix_present_flag 
     298        { 
     299            for (int idx = 0; idx < ((chroma_format_idc != 3) ? 8 : 12); ++idx) 
     300            { 
     301                get_bits1(gb);  // scaling_list 
     302            } 
     303        } 
     304    } 
     305 
     306    log2_max_frame_num = get_ue_golomb(gb) + 4; 
     307 
     308    uint       pic_order_cnt_type; 
     309    uint       log2_max_pic_order_cnt_lsb; 
     310    bool       delta_pic_order_always_zero_flag; 
     311    int        offset_for_non_ref_pic; 
     312    int        offset_for_top_to_bottom_field; 
     313    uint       tmp; 
     314    uint       num_ref_frames; 
     315    bool       gaps_in_frame_num_allowed_flag; 
     316    uint       pic_width_in_mbs; 
     317    uint       pic_height_in_map_units; 
     318 
     319    pic_order_cnt_type = get_ue_golomb(gb); 
     320    if (pic_order_cnt_type == 0) 
     321        log2_max_pic_order_cnt_lsb = get_ue_golomb(gb) + 4; 
     322    else if (pic_order_cnt_type == 1) 
     323    { 
     324        delta_pic_order_always_zero_flag = get_bits1(gb); 
     325        offset_for_non_ref_pic = get_se_golomb(gb); 
     326        offset_for_top_to_bottom_field = get_se_golomb(gb); 
     327        tmp = get_ue_golomb(gb); 
     328        for (uint idx = 0; idx < tmp; ++idx) 
     329            get_se_golomb(gb);  // offset_for_ref_frame[i] 
     330    } 
     331 
     332    num_ref_frames = get_ue_golomb(gb); 
     333    gaps_in_frame_num_allowed_flag = get_bits1(gb); 
     334    pic_width_in_mbs = get_ue_golomb(gb) + 1; 
     335    pic_height_in_map_units = get_ue_golomb(gb) + 1; 
     336    frame_mbs_only_flag = get_bits1(gb); 
     337 
     338} 
     339 
     340 
    178341} // namespace H264 
  • libs/libmythtv/mpeg/h264utils.h

    old new  
    3535 
    3636#include <stdint.h> 
    3737 
     38extern "C" { 
     39#include "golomb.h" 
     40} 
     41 
    3842namespace H264 
    3943{ 
    4044 
     
    174178 
    175179  private: 
    176180    void KeyframePredicate(const uint8_t new_first_NAL_byte); /* throw() */ 
     181    void decode_Header(GetBitContext * gb); 
     182    void decode_SPS(GetBitContext * gb); 
    177183 
    178184    bool    errored; 
    179185    bool    state_changed; 
     
    182188    int64_t  sync_stream_offset; 
    183189 
    184190    uint8_t first_NAL_byte; 
     191    int     log2_max_frame_num; 
     192    int     frame_num, prev_frame_num; 
    185193 
    186194    bool    saw_AU_delimiter; 
    187195    bool    saw_first_VCL_NAL_unit; 
    188196    bool    saw_sps; 
     197    bool    new_VLC_NAL; 
     198 
     199    bool    separate_colour_plane_flag; 
     200    bool    frame_mbs_only_flag; 
     201    bool    prev_field_pic_flag; 
     202    bool    prev_bottom_field_flag; 
     203    uint    prev_pic_parameter_set_id; 
     204 
    189205 
    190206    bool    did_evaluate_once; 
    191207    bool    keyframe; 
    192208    int64_t keyframe_sync_stream_offset; 
     209 
     210    GetBitContext gb; 
    193211}; 
    194212 
    195213} // namespace H264