Ticket #5443: h264-parse-frame_num.patch

File h264-parse-frame_num.patch, 5.3 KB (added by jppoet@…, 4 years ago)

Parse frame_num from H.264

  • libs/libmythtv/dtvrecorder.cpp

     
    532532                hasKeyFrame = true; 
    533533                hasFrame = true; 
    534534            } 
    535  
    536             if (_h264_kf_seq.IsOnFrame()) 
     535            else if (_h264_kf_seq.IsOnFrame()) 
    537536                hasFrame = true; 
    538537        } 
    539538    } // for (; i < TSPacket::SIZE; i++) 
  • libs/libmythtv/mpeg/h264utils.h

     
    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    separate_colour_plane_flag; 
    189198 
    190199    bool    did_evaluate_once; 
    191200    bool    keyframe; 
    192201    int64_t keyframe_sync_stream_offset; 
     202 
     203    GetBitContext gb; 
    193204}; 
    194205 
    195206} // namespace H264 
  • libs/libmythtv/mpeg/h264utils.cpp

     
    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; 
    6874 
    6975    did_evaluate_once = false; 
    7076    keyframe = false; 
     
    154160        if ((sync_accumulator & 0xffffff00) == 0x00000100) 
    155161        { 
    156162            uint8_t k = *(local_bytes-1); 
     163            uint8_t NAL_type = k & 0x1f; 
    157164            sync_stream_offset = stream_offset; 
    158165            keyframe = false; 
    159166 
    160167            KeyframePredicate(k); 
    161168            first_NAL_byte = k; 
    162169 
     170            if (NAL_type == NALUnitType::SPS || 
     171                NAL_type == NALUnitType::SLICE || 
     172                NAL_type == NALUnitType::SLICE_DPA) { 
     173            /* 
     174              bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE 
     175              bytes larger then the actual read bits 
     176            */ 
     177                if (local_bytes + 20 + FF_INPUT_BUFFER_PADDING_SIZE < 
     178                    local_bytes_end) { 
     179                    init_get_bits(&gb, local_bytes, 
     180                                  8 * (local_bytes_end - local_bytes)); 
     181                     
     182                    if (NAL_type == NALUnitType::SPS) 
     183                        decode_SPS(&gb); 
     184                    else 
     185                        decode_Header(&gb); 
     186                } 
     187                 
     188            } 
     189            else if (NAL_type == NALUnitType::SLICE_IDR) 
     190                frame_num = 0; 
     191 
    163192            return local_bytes - bytes; 
    164193        } 
    165194    } 
     
    175204    return saw_first_VCL_NAL_unit; 
    176205} 
    177206 
     207void KeyframeSequencer::decode_Header(GetBitContext * gb) 
     208{ 
     209    uint first_mb_in_slice; 
     210    uint slice_type; 
     211    uint pic_parameter_set_id; 
     212     
     213    if (log2_max_frame_num < 1) 
     214    { 
     215        std::cerr 
     216            << "KeyframeSequencer::decode_Header: SPS has not been parsed!\n"; 
     217        return; 
     218    } 
     219 
     220    prev_frame_num = frame_num; 
     221 
     222    first_mb_in_slice = get_ue_golomb(gb); 
     223    slice_type = get_ue_golomb(gb); 
     224    pic_parameter_set_id = get_ue_golomb(gb); 
     225     
     226    if (separate_colour_plane_flag) 
     227        get_bits(gb, 2);  // colour_plane_id 
     228     
     229    frame_num = get_bits(gb, log2_max_frame_num); 
     230} 
     231 
     232/* 
     233 * Just the parts we need -- libavcodec used for example 
     234 */ 
     235void KeyframeSequencer::decode_SPS(GetBitContext * gb) 
     236{ 
     237    int profile_idc, chroma_format_idc; 
     238    int idx; 
     239 
     240    profile_idc = get_bits(gb, 8); // profile_idc 
     241    get_bits1(gb);   // constraint_set0_flag 
     242    get_bits1(gb);   // constraint_set1_flag 
     243    get_bits1(gb);   // constraint_set2_flag 
     244    get_bits1(gb);   // constraint_set3_flag 
     245    get_bits(gb, 4); // reserved 
     246    get_bits(gb, 8); // level_idc 
     247    get_ue_golomb(gb);  // sps_id 
     248 
     249    if(profile_idc >= 100){ // high profile 
     250        if((chroma_format_idc = get_ue_golomb(gb)) == 3) // chroma_format_idc 
     251            separate_colour_plane_flag = (get_bits1(gb) == 1); 
     252        get_ue_golomb(gb);  // bit_depth_luma_minus8 
     253        get_ue_golomb(gb);  // bit_depth_chroma_minus8 
     254        get_bits1(gb);      // qpprime_y_zero_transform_bypass_flag 
     255 
     256        if (get_bits1(gb))      // seq_scaling_matrix_present_flag 
     257        { 
     258            for (idx = 0; idx < ((chroma_format_idc != 3) ? 8 : 12); ++idx) 
     259            { 
     260                get_bits1(gb);  // scaling_list 
     261            } 
     262        } 
     263    } 
     264 
     265    log2_max_frame_num = get_ue_golomb(gb) + 4; 
     266} 
     267 
    178268} // namespace H264 
     269