Ticket #5443: h264-parse-field-flag.diff

File h264-parse-field-flag.diff, 7.5 KB (added by jppoet@…, 17 years ago)

Update H.264 processing to parse bottom_field_flag and use it for frame detection

  • 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    new_VLC_NAL;
    189198
     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
     205
    190206    bool    did_evaluate_once;
    191207    bool    keyframe;
    192208    int64_t keyframe_sync_stream_offset;
     209
     210    GetBitContext gb;
    193211};
    194212
    195213} // 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;
     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
    178340} // namespace H264