00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "H264VideoStreamFramer.hh"
00022 #include "MPEGVideoStreamParser.hh"
00023 #include "BitVector.hh"
00024 #include "H264VideoRTPSource.hh"
00025
00027
00028 class H264VideoStreamParser: public MPEGVideoStreamParser {
00029 public:
00030 H264VideoStreamParser(H264VideoStreamFramer* usingSource, FramedSource* inputSource, Boolean includeStartCodeInOutput);
00031 virtual ~H264VideoStreamParser();
00032
00033 private:
00034 virtual void flushInput();
00035 virtual unsigned parse();
00036
00037 private:
00038 H264VideoStreamFramer* usingSource() {
00039 return (H264VideoStreamFramer*)fUsingSource;
00040 }
00041
00042 void removeEmulationBytes(u_int8_t* nalUnitCopy, unsigned maxSize, unsigned& nalUnitCopySize);
00043
00044 void analyze_seq_parameter_set_data(unsigned& num_units_in_tick, unsigned& time_scale, unsigned& fixed_frame_rate_flag);
00045 void analyze_vui_parameters(BitVector& bv,
00046 unsigned& num_units_in_tick, unsigned& time_scale, unsigned& fixed_frame_rate_flag);
00047 #ifdef DO_FULL_SPS_PARSING
00048 void analyze_hrd_parameters(BitVector& bv);
00049 #endif
00050 void analyze_sei_data();
00051 void analyze_slice_header(u_int8_t* start, u_int8_t* end, u_int8_t nal_unit_type,
00052 unsigned &frame_num, unsigned &pic_parameter_set_id, unsigned& idr_pic_id,
00053 Boolean& field_pic_flag, Boolean& bottom_field_flag);
00054
00055 private:
00056 unsigned fOutputStartCodeSize;
00057 Boolean fHaveSeenFirstStartCode, fHaveSeenFirstByteOfNALUnit;
00058 u_int8_t fFirstByteOfNALUnit;
00059
00060
00061 unsigned log2_max_frame_num;
00062 Boolean separate_colour_plane_flag;
00063 Boolean frame_mbs_only_flag;
00064 };
00065
00066
00068
00069 H264VideoStreamFramer* H264VideoStreamFramer
00070 ::createNew(UsageEnvironment& env, FramedSource* inputSource, Boolean includeStartCodeInOutput) {
00071 return new H264VideoStreamFramer(env, inputSource, True, includeStartCodeInOutput);
00072 }
00073
00074 H264VideoStreamFramer
00075 ::H264VideoStreamFramer(UsageEnvironment& env, FramedSource* inputSource, Boolean createParser, Boolean includeStartCodeInOutput)
00076 : MPEGVideoStreamFramer(env, inputSource),
00077 fIncludeStartCodeInOutput(includeStartCodeInOutput),
00078 fLastSeenSPS(NULL), fLastSeenSPSSize(0), fLastSeenPPS(NULL), fLastSeenPPSSize(0) {
00079 fParser = createParser
00080 ? new H264VideoStreamParser(this, inputSource, includeStartCodeInOutput)
00081 : NULL;
00082 fNextPresentationTime = fPresentationTimeBase;
00083 fFrameRate = 25.0;
00084 }
00085
00086 H264VideoStreamFramer::~H264VideoStreamFramer() {
00087 delete[] fLastSeenSPS;
00088 delete[] fLastSeenPPS;
00089 }
00090
00091 void H264VideoStreamFramer::setSPSandPPS(char const* sPropParameterSetsStr) {
00092 unsigned numSPropRecords;
00093 SPropRecord* sPropRecords = parseSPropParameterSets(sPropParameterSetsStr, numSPropRecords);
00094 for (unsigned i = 0; i < numSPropRecords; ++i) {
00095 if (sPropRecords[i].sPropLength == 0) continue;
00096 u_int8_t nal_unit_type = (sPropRecords[i].sPropBytes[0])&0x1F;
00097 if (nal_unit_type == 7) {
00098 saveCopyOfSPS(sPropRecords[i].sPropBytes, sPropRecords[i].sPropLength);
00099 } else if (nal_unit_type == 8) {
00100 saveCopyOfPPS(sPropRecords[i].sPropBytes, sPropRecords[i].sPropLength);
00101 }
00102 }
00103 delete[] sPropRecords;
00104 }
00105
00106 void H264VideoStreamFramer::saveCopyOfSPS(u_int8_t* from, unsigned size) {
00107 delete[] fLastSeenSPS;
00108 fLastSeenSPS = new u_int8_t[size];
00109 memmove(fLastSeenSPS, from, size);
00110
00111 fLastSeenSPSSize = size;
00112 }
00113
00114 void H264VideoStreamFramer::saveCopyOfPPS(u_int8_t* from, unsigned size) {
00115 delete[] fLastSeenPPS;
00116 fLastSeenPPS = new u_int8_t[size];
00117 memmove(fLastSeenPPS, from, size);
00118
00119 fLastSeenPPSSize = size;
00120 }
00121
00122 Boolean H264VideoStreamFramer::isH264VideoStreamFramer() const {
00123 return True;
00124 }
00125
00126
00128
00129 H264VideoStreamParser
00130 ::H264VideoStreamParser(H264VideoStreamFramer* usingSource, FramedSource* inputSource, Boolean includeStartCodeInOutput)
00131 : MPEGVideoStreamParser(usingSource, inputSource),
00132 fOutputStartCodeSize(includeStartCodeInOutput ? 4 : 0), fHaveSeenFirstStartCode(False), fHaveSeenFirstByteOfNALUnit(False),
00133
00134 log2_max_frame_num(5), separate_colour_plane_flag(False), frame_mbs_only_flag(True) {
00135 }
00136
00137 H264VideoStreamParser::~H264VideoStreamParser() {
00138 }
00139
00140 void H264VideoStreamParser::removeEmulationBytes(u_int8_t* nalUnitCopy, unsigned maxSize, unsigned& nalUnitCopySize) {
00141 u_int8_t* nalUnitOrig = fStartOfFrame + fOutputStartCodeSize;
00142 unsigned const NumBytesInNALunit = fTo - nalUnitOrig;
00143 if (NumBytesInNALunit > maxSize) return;
00144 nalUnitCopySize = 0;
00145 for (unsigned i = 0; i < NumBytesInNALunit; ++i) {
00146 if (i+2 < NumBytesInNALunit && nalUnitOrig[i] == 0 && nalUnitOrig[i+1] == 0 && nalUnitOrig[i+2] == 3) {
00147 nalUnitCopy[nalUnitCopySize++] = nalUnitOrig[i++];
00148 nalUnitCopy[nalUnitCopySize++] = nalUnitOrig[i++];
00149 } else {
00150 nalUnitCopy[nalUnitCopySize++] = nalUnitOrig[i];
00151 }
00152 }
00153 }
00154
00155 #ifdef DEBUG
00156 char const* nal_unit_type_description[32] = {
00157 "Unspecified",
00158 "Coded slice of a non-IDR picture",
00159 "Coded slice data partition A",
00160 "Coded slice data partition B",
00161 "Coded slice data partition C",
00162 "Coded slice of an IDR picture",
00163 "Supplemental enhancement information (SEI)",
00164 "Sequence parameter set",
00165 "Picture parameter set",
00166 "Access unit delimiter",
00167 "End of sequence",
00168 "End of stream",
00169 "Filler data",
00170 "Sequence parameter set extension",
00171 "Prefix NAL unit",
00172 "Subset sequence parameter set",
00173 "Reserved",
00174 "Reserved",
00175 "Reserved",
00176 "Coded slice of an auxiliary coded picture without partitioning",
00177 "Coded slice extension",
00178 "Reserved",
00179 "Reserved",
00180 "Reserved",
00181 "Unspecified",
00182 "Unspecified",
00183 "Unspecified",
00184 "Unspecified",
00185 "Unspecified",
00186 "Unspecified",
00187 "Unspecified",
00188 "Unspecified"
00189 };
00190 #endif
00191
00192 #ifdef DEBUG
00193 static unsigned numDebugTabs = 1;
00194 #define DEBUG_PRINT_TABS for (unsigned _i = 0; _i < numDebugTabs; ++_i) fprintf(stderr, "\t")
00195 #define DEBUG_PRINT(x) do { DEBUG_PRINT_TABS; fprintf(stderr, "%s: %d\n", #x, x); } while (0)
00196 #define DEBUG_STR(x) do { DEBUG_PRINT_TABS; fprintf(stderr, "%s\n", x); } while (0)
00197 class DebugTab {
00198 public:
00199 DebugTab() {++numDebugTabs;}
00200 ~DebugTab() {--numDebugTabs;}
00201 };
00202 #define DEBUG_TAB DebugTab dummy
00203 #else
00204 #define DEBUG_PRINT(x) do {x = x;} while (0)
00205
00206 #define DEBUG_STR(x) do {} while (0)
00207 #define DEBUG_TAB do {} while (0)
00208 #endif
00209
00210 #ifdef DO_FULL_SPS_PARSING
00211 void H264VideoStreamParser::analyze_hrd_parameters(BitVector& bv) {
00212 DEBUG_STR("BEGIN hrd_parameters");
00213 unsigned cpb_cnt_minus1 = bv.get_expGolomb();
00214 DEBUG_PRINT(cpb_cnt_minus1);
00215 unsigned bit_rate_scale = bv.getBits(4);
00216 DEBUG_PRINT(bit_rate_scale);
00217 unsigned cpb_size_scale = bv.getBits(4);
00218 DEBUG_PRINT(cpb_size_scale);
00219 for (unsigned SchedSelIdx = 0; SchedSelIdx <= cpb_cnt_minus1; ++SchedSelIdx) {
00220 DEBUG_TAB;
00221 unsigned bit_rate_value_minus1 = bv.get_expGolomb();
00222 DEBUG_PRINT(bit_rate_value_minus1);
00223 unsigned cpb_size_value_minus1 = bv.get_expGolomb();
00224 DEBUG_PRINT(cpb_size_value_minus1);
00225 unsigned cbr_flag = bv.get1Bit();
00226 DEBUG_PRINT(cbr_flag);
00227 }
00228 unsigned initial_cpb_removal_delay_length_minus1 = bv.getBits(5);
00229 DEBUG_PRINT(initial_cpb_removal_delay_length_minus1);
00230 unsigned cpb_removal_delay_length_minus1 = bv.getBits(5);
00231 DEBUG_PRINT(cpb_removal_delay_length_minus1);
00232 unsigned dpb_output_delay_length_minus1 = bv.getBits(5);
00233 DEBUG_PRINT(dpb_output_delay_length_minus1);
00234 unsigned time_offset_length = bv.getBits(5);
00235 DEBUG_PRINT(time_offset_length);
00236 DEBUG_STR("END hrd_parameters");
00237 }
00238 #endif
00239
00240 void H264VideoStreamParser
00241 ::analyze_vui_parameters(BitVector& bv,
00242 unsigned& num_units_in_tick, unsigned& time_scale, unsigned& fixed_frame_rate_flag) {
00243 DEBUG_STR("BEGIN vui_parameters");
00244 unsigned aspect_ratio_info_present_flag = bv.get1Bit();
00245 DEBUG_PRINT(aspect_ratio_info_present_flag);
00246 if (aspect_ratio_info_present_flag) {
00247 DEBUG_TAB;
00248 unsigned aspect_ratio_idc = bv.getBits(8);
00249 DEBUG_PRINT(aspect_ratio_idc);
00250 if (aspect_ratio_idc == 255) {
00251 bv.skipBits(32);
00252 }
00253 }
00254 unsigned overscan_info_present_flag = bv.get1Bit();
00255 DEBUG_PRINT(overscan_info_present_flag);
00256 if (overscan_info_present_flag) {
00257 bv.skipBits(1);
00258 }
00259 unsigned video_signal_type_present_flag = bv.get1Bit();
00260 DEBUG_PRINT(video_signal_type_present_flag);
00261 if (video_signal_type_present_flag) {
00262 DEBUG_TAB;
00263 bv.skipBits(4);
00264 unsigned colour_description_present_flag = bv.get1Bit();
00265 DEBUG_PRINT(colour_description_present_flag);
00266 if (colour_description_present_flag) {
00267 bv.skipBits(24);
00268 }
00269 }
00270 unsigned chroma_loc_info_present_flag = bv.get1Bit();
00271 DEBUG_PRINT(chroma_loc_info_present_flag);
00272 if (chroma_loc_info_present_flag) {
00273 (void)bv.get_expGolomb();
00274 (void)bv.get_expGolomb();
00275 }
00276 unsigned timing_info_present_flag = bv.get1Bit();
00277 DEBUG_PRINT(timing_info_present_flag);
00278 if (timing_info_present_flag) {
00279 DEBUG_TAB;
00280 num_units_in_tick = bv.getBits(32);
00281 DEBUG_PRINT(num_units_in_tick);
00282 time_scale = bv.getBits(32);
00283 DEBUG_PRINT(time_scale);
00284 fixed_frame_rate_flag = bv.get1Bit();
00285 DEBUG_PRINT(fixed_frame_rate_flag);
00286 }
00287 #ifdef DO_FULL_SPS_PARSING
00288 unsigned nal_hrd_parameters_present_flag = bv.get1Bit();
00289 DEBUG_PRINT(nal_hrd_parameters_present_flag);
00290 if (nal_hrd_parameters_present_flag) {
00291 DEBUG_TAB;
00292 analyze_hrd_parameters(bv);
00293 }
00294 unsigned vcl_hrd_parameters_present_flag = bv.get1Bit();
00295 DEBUG_PRINT(vcl_hrd_parameters_present_flag);
00296 if (vcl_hrd_parameters_present_flag) {
00297 DEBUG_TAB;
00298 analyze_hrd_parameters(bv);
00299 }
00300 if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {
00301 bv.skipBits(1);
00302 }
00303 bv.skipBits(1);
00304 unsigned bitstream_restriction_flag = bv.get1Bit();
00305 DEBUG_PRINT(bitstream_restriction_flag);
00306 if (bitstream_restriction_flag) {
00307 bv.skipBits(1);
00308 (void)bv.get_expGolomb();
00309 (void)bv.get_expGolomb();
00310 (void)bv.get_expGolomb();
00311 (void)bv.get_expGolomb();
00312 (void)bv.get_expGolomb();
00313 (void)bv.get_expGolomb();
00314 }
00315 DEBUG_STR("END vui_parameters");
00316 #endif
00317 }
00318
00319 #define SPS_MAX_SIZE 1000 // larger than the largest possible SPS (Sequence Parameter Set) NAL unit
00320
00321 void H264VideoStreamParser
00322 ::analyze_seq_parameter_set_data(unsigned& num_units_in_tick, unsigned& time_scale, unsigned& fixed_frame_rate_flag) {
00323 num_units_in_tick = time_scale = fixed_frame_rate_flag = 0;
00324
00325
00326 u_int8_t sps[SPS_MAX_SIZE];
00327 unsigned spsSize;
00328 removeEmulationBytes(sps, sizeof sps, spsSize);
00329
00330 BitVector bv(sps, 0, 8*spsSize);
00331
00332 bv.skipBits(8);
00333 unsigned profile_idc = bv.getBits(8);
00334 DEBUG_PRINT(profile_idc);
00335 unsigned constraint_setN_flag = bv.getBits(8);
00336 DEBUG_PRINT(constraint_setN_flag);
00337 unsigned level_idc = bv.getBits(8);
00338 DEBUG_PRINT(level_idc);
00339 unsigned seq_parameter_set_id = bv.get_expGolomb();
00340 DEBUG_PRINT(seq_parameter_set_id);
00341 if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118 || profile_idc == 128 ) {
00342 DEBUG_TAB;
00343 unsigned chroma_format_idc = bv.get_expGolomb();
00344 DEBUG_PRINT(chroma_format_idc);
00345 if (chroma_format_idc == 3) {
00346 DEBUG_TAB;
00347 separate_colour_plane_flag = bv.get1Bit();
00348 DEBUG_PRINT(separate_colour_plane_flag);
00349 }
00350 (void)bv.get_expGolomb();
00351 (void)bv.get_expGolomb();
00352 bv.skipBits(1);
00353 unsigned seq_scaling_matrix_present_flag = bv.get1Bit();
00354 DEBUG_PRINT(seq_scaling_matrix_present_flag);
00355 if (seq_scaling_matrix_present_flag) {
00356 for (int i = 0; i < ((chroma_format_idc != 3) ? 8 : 12); ++i) {
00357 DEBUG_TAB;
00358 DEBUG_PRINT(i);
00359 unsigned seq_scaling_list_present_flag = bv.get1Bit();
00360 DEBUG_PRINT(seq_scaling_list_present_flag);
00361 if (seq_scaling_list_present_flag) {
00362 DEBUG_TAB;
00363 unsigned sizeOfScalingList = i < 6 ? 16 : 64;
00364 unsigned lastScale = 8;
00365 unsigned nextScale = 8;
00366 for (unsigned j = 0; j < sizeOfScalingList; ++j) {
00367 DEBUG_TAB;
00368 DEBUG_PRINT(j);
00369 DEBUG_PRINT(nextScale);
00370 if (nextScale != 0) {
00371 DEBUG_TAB;
00372 unsigned delta_scale = bv.get_expGolomb();
00373 DEBUG_PRINT(delta_scale);
00374 nextScale = (lastScale + delta_scale + 256) % 256;
00375 }
00376 lastScale = (nextScale == 0) ? lastScale : nextScale;
00377 DEBUG_PRINT(lastScale);
00378 }
00379 }
00380 }
00381 }
00382 }
00383 unsigned log2_max_frame_num_minus4 = bv.get_expGolomb();
00384 DEBUG_PRINT(log2_max_frame_num_minus4);
00385 log2_max_frame_num = log2_max_frame_num_minus4 + 4;
00386 unsigned pic_order_cnt_type = bv.get_expGolomb();
00387 DEBUG_PRINT(pic_order_cnt_type);
00388 if (pic_order_cnt_type == 0) {
00389 DEBUG_TAB;
00390 unsigned log2_max_pic_order_cnt_lsb_minus4 = bv.get_expGolomb();
00391 DEBUG_PRINT(log2_max_pic_order_cnt_lsb_minus4);
00392 } else if (pic_order_cnt_type == 1) {
00393 DEBUG_TAB;
00394 bv.skipBits(1);
00395 (void)bv.get_expGolomb();
00396 (void)bv.get_expGolomb();
00397 unsigned num_ref_frames_in_pic_order_cnt_cycle = bv.get_expGolomb();
00398 DEBUG_PRINT(num_ref_frames_in_pic_order_cnt_cycle);
00399 for (unsigned i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) {
00400 (void)bv.get_expGolomb();
00401 }
00402 }
00403 unsigned max_num_ref_frames = bv.get_expGolomb();
00404 DEBUG_PRINT(max_num_ref_frames);
00405 unsigned gaps_in_frame_num_value_allowed_flag = bv.get1Bit();
00406 DEBUG_PRINT(gaps_in_frame_num_value_allowed_flag);
00407 unsigned pic_width_in_mbs_minus1 = bv.get_expGolomb();
00408 DEBUG_PRINT(pic_width_in_mbs_minus1);
00409 unsigned pic_height_in_map_units_minus1 = bv.get_expGolomb();
00410 DEBUG_PRINT(pic_height_in_map_units_minus1);
00411 frame_mbs_only_flag = bv.get1Bit();
00412 DEBUG_PRINT(frame_mbs_only_flag);
00413 if (!frame_mbs_only_flag) {
00414 bv.skipBits(1);
00415 }
00416 bv.skipBits(1);
00417 unsigned frame_cropping_flag = bv.get1Bit();
00418 DEBUG_PRINT(frame_cropping_flag);
00419 if (frame_cropping_flag) {
00420 (void)bv.get_expGolomb();
00421 (void)bv.get_expGolomb();
00422 (void)bv.get_expGolomb();
00423 (void)bv.get_expGolomb();
00424 }
00425 unsigned vui_parameters_present_flag = bv.get1Bit();
00426 DEBUG_PRINT(vui_parameters_present_flag);
00427 if (vui_parameters_present_flag) {
00428 DEBUG_TAB;
00429 analyze_vui_parameters(bv,num_units_in_tick, time_scale, fixed_frame_rate_flag);
00430 }
00431 }
00432
00433 #define SEI_MAX_SIZE 5000 // larger than the largest possible SEI NAL unit
00434
00435 #ifdef DEBUG
00436 #define MAX_SEI_PAYLOAD_TYPE_DESCRIPTION 46
00437 char const* sei_payloadType_description[MAX_SEI_PAYLOAD_TYPE_DESCRIPTION+1] = {
00438 "buffering_period",
00439 "pic_timing",
00440 "pan_scan_rect",
00441 "filler_payload",
00442 "user_data_registered_itu_t_t35",
00443 "user_data_unregistered",
00444 "recovery_point",
00445 "dec_ref_pic_marking_repetition",
00446 "spare_pic",
00447 "scene_info",
00448 "sub_seq_info",
00449 "sub_seq_layer_characteristics",
00450 "sub_seq_characteristics",
00451 "full_frame_freeze",
00452 "full_frame_freeze_release",
00453 "full_frame_snapshot",
00454 "progressive_refinement_segment_start",
00455 "progressive_refinement_segment_end",
00456 "motion_constrained_slice_group_set",
00457 "film_grain_characteristics",
00458 "deblocking_filter_display_preference",
00459 "stereo_video_info",
00460 "post_filter_hint",
00461 "tone_mapping_info",
00462 "scalability_info",
00463 "sub_pic_scalable_layer",
00464 "non_required_layer_rep",
00465 "priority_layer_info",
00466 "layers_not_present",
00467 "layer_dependency_change",
00468 "scalable_nesting",
00469 "base_layer_temporal_hrd",
00470 "quality_layer_integrity_check",
00471 "redundant_pic_property",
00472 "tl0_dep_rep_index",
00473 "tl_switching_point",
00474 "parallel_decoding_info",
00475 "mvc_scalable_nesting",
00476 "view_scalability_info",
00477 "multiview_scene_info",
00478 "multiview_acquisition_info",
00479 "non_required_view_component",
00480 "view_dependency_change",
00481 "operation_points_not_present",
00482 "base_view_temporal_hrd",
00483 "frame_packing_arrangement",
00484 "reserved_sei_message"
00485 };
00486 #endif
00487
00488 void H264VideoStreamParser::analyze_sei_data() {
00489
00490 u_int8_t sei[SEI_MAX_SIZE];
00491 unsigned seiSize;
00492 removeEmulationBytes(sei, sizeof sei, seiSize);
00493
00494 unsigned j = 1;
00495 while (j < seiSize) {
00496 unsigned payloadType = 0;
00497 do {
00498 payloadType += sei[j];
00499 } while (sei[j++] == 255 && j < seiSize);
00500 if (j >= seiSize) break;
00501
00502 unsigned payloadSize = 0;
00503 do {
00504 payloadSize += sei[j];
00505 } while (sei[j++] == 255 && j < seiSize);
00506 if (j >= seiSize) break;
00507
00508 #ifdef DEBUG
00509 unsigned descriptionNum = payloadType <= MAX_SEI_PAYLOAD_TYPE_DESCRIPTION ? payloadType : MAX_SEI_PAYLOAD_TYPE_DESCRIPTION;
00510 fprintf(stderr, "\tpayloadType %d (\"%s\"); payloadSize %d\n", payloadType, sei_payloadType_description[descriptionNum], payloadSize);
00511 #endif
00512 j += payloadSize;
00513 }
00514 }
00515
00516 void H264VideoStreamParser
00517 ::analyze_slice_header(u_int8_t* start, u_int8_t* end, u_int8_t nal_unit_type,
00518 unsigned &frame_num, unsigned &pic_parameter_set_id, unsigned& idr_pic_id,
00519 Boolean& field_pic_flag, Boolean& bottom_field_flag) {
00520 BitVector bv(start, 0, 8*(end-start));
00521
00522
00523 field_pic_flag = bottom_field_flag = 0;
00524
00525
00526 bv.skipBits(8);
00527 unsigned first_mb_in_slice = bv.get_expGolomb();
00528 DEBUG_PRINT(first_mb_in_slice);
00529 unsigned slice_type = bv.get_expGolomb();
00530 DEBUG_PRINT(slice_type);
00531 pic_parameter_set_id = bv.get_expGolomb();
00532 DEBUG_PRINT(pic_parameter_set_id);
00533 if (separate_colour_plane_flag) {
00534 bv.skipBits(2);
00535 }
00536 frame_num = bv.getBits(log2_max_frame_num);
00537 DEBUG_PRINT(frame_num);
00538 if (!frame_mbs_only_flag) {
00539 DEBUG_TAB;
00540 field_pic_flag = bv.get1Bit();
00541 DEBUG_PRINT(field_pic_flag);
00542 if (field_pic_flag) {
00543 DEBUG_TAB;
00544 bottom_field_flag = bv.get1Bit();
00545 DEBUG_PRINT(bottom_field_flag);
00546 }
00547 }
00548 Boolean IdrPicFlag = nal_unit_type == 5;
00549 if (IdrPicFlag) {
00550 DEBUG_TAB;
00551 idr_pic_id = bv.get_expGolomb();
00552 DEBUG_PRINT(idr_pic_id);
00553 }
00554
00555 }
00556
00557 void H264VideoStreamParser::flushInput() {
00558 fHaveSeenFirstStartCode = False;
00559 fHaveSeenFirstByteOfNALUnit = False;
00560
00561 StreamParser::flushInput();
00562 }
00563
00564 #define NUM_NEXT_SLICE_HEADER_BYTES_TO_ANALYZE 12
00565
00566 unsigned H264VideoStreamParser::parse() {
00567 try {
00568
00569 if (!fHaveSeenFirstStartCode) {
00570
00571 u_int32_t first4Bytes;
00572 while ((first4Bytes = test4Bytes()) != 0x00000001) {
00573 get1Byte(); setParseState();
00574 }
00575 skipBytes(4);
00576
00577 setParseState();
00578 fHaveSeenFirstStartCode = True;
00579 }
00580
00581 if (fOutputStartCodeSize > 0) {
00582
00583 save4Bytes(0x00000001);
00584 }
00585
00586
00587
00588 if (haveSeenEOF()) {
00589
00590
00591 unsigned remainingDataSize = totNumValidBytes() - curOffset();
00592 while (remainingDataSize > 0) {
00593 saveByte(get1Byte());
00594 --remainingDataSize;
00595 }
00596
00597 if (!fHaveSeenFirstByteOfNALUnit) {
00598
00599 (void)get1Byte();
00600 return 0;
00601 }
00602 #ifdef DEBUG
00603 fprintf(stderr, "This NAL unit (%d bytes) ends with EOF\n", curFrameSize()-fOutputStartCodeSize);
00604 #endif
00605 } else {
00606 u_int32_t next4Bytes = test4Bytes();
00607 if (!fHaveSeenFirstByteOfNALUnit) {
00608 fFirstByteOfNALUnit = next4Bytes>>24;
00609 fHaveSeenFirstByteOfNALUnit = True;
00610 }
00611 while (next4Bytes != 0x00000001 && (next4Bytes&0xFFFFFF00) != 0x00000100) {
00612
00613 if ((unsigned)(next4Bytes&0xFF) > 1) {
00614
00615 save4Bytes(next4Bytes);
00616 skipBytes(4);
00617 } else {
00618
00619 saveByte(next4Bytes>>24);
00620 skipBytes(1);
00621 }
00622 setParseState();
00623 next4Bytes = test4Bytes();
00624 }
00625
00626
00627 if (next4Bytes == 0x00000001) {
00628 skipBytes(4);
00629 } else {
00630 skipBytes(3);
00631 }
00632 }
00633
00634 u_int8_t nal_ref_idc = (fFirstByteOfNALUnit&0x60)>>5;
00635 u_int8_t nal_unit_type = fFirstByteOfNALUnit&0x1F;
00636 fHaveSeenFirstByteOfNALUnit = False;
00637 #ifdef DEBUG
00638 fprintf(stderr, "Parsed %d-byte NAL-unit (nal_ref_idc: %d, nal_unit_type: %d (\"%s\"))\n",
00639 curFrameSize()-fOutputStartCodeSize, nal_ref_idc, nal_unit_type, nal_unit_type_description[nal_unit_type]);
00640 #endif
00641
00642 switch (nal_unit_type) {
00643 case 6: {
00644 analyze_sei_data();
00645
00646 break;
00647 }
00648 case 7: {
00649
00650 usingSource()->saveCopyOfSPS(fStartOfFrame + fOutputStartCodeSize, fTo - fStartOfFrame - fOutputStartCodeSize);
00651
00652
00653 unsigned num_units_in_tick, time_scale, fixed_frame_rate_flag;
00654 analyze_seq_parameter_set_data(num_units_in_tick, time_scale, fixed_frame_rate_flag);
00655 if (time_scale > 0 && num_units_in_tick > 0) {
00656 usingSource()->fFrameRate = time_scale/(2.0*num_units_in_tick);
00657 #ifdef DEBUG
00658 fprintf(stderr, "Set frame rate to %f fps\n", usingSource()->fFrameRate);
00659 if (fixed_frame_rate_flag == 0) {
00660 fprintf(stderr, "\tWARNING: \"fixed_frame_rate_flag\" was not set\n");
00661 }
00662 #endif
00663 } else {
00664 #ifdef DEBUG
00665 fprintf(stderr, "\tThis \"Sequence Parameter Set\" NAL unit contained no frame rate information, so we use a default frame rate of %f fps\n", usingSource()->fFrameRate);
00666 #endif
00667 }
00668 break;
00669 }
00670 case 8: {
00671
00672 usingSource()->saveCopyOfPPS(fStartOfFrame + fOutputStartCodeSize, fTo - fStartOfFrame - fOutputStartCodeSize);
00673 }
00674 }
00675
00676 usingSource()->setPresentationTime();
00677 #ifdef DEBUG
00678 unsigned long secs = (unsigned long)usingSource()->fPresentationTime.tv_sec;
00679 unsigned uSecs = (unsigned)usingSource()->fPresentationTime.tv_usec;
00680 fprintf(stderr, "\tPresentation time: %lu.%06u\n", secs, uSecs);
00681 #endif
00682
00683
00684
00685
00686 Boolean thisNALUnitEndsAccessUnit = False;
00687 if (haveSeenEOF()) {
00688
00689 thisNALUnitEndsAccessUnit = True;
00690 } else {
00691 Boolean const isVCL = nal_unit_type <= 5 && nal_unit_type > 0;
00692 if (isVCL) {
00693 u_int32_t first4BytesOfNextNALUnit = test4Bytes();
00694 u_int8_t firstByteOfNextNALUnit = first4BytesOfNextNALUnit>>24;
00695 u_int8_t next_nal_ref_idc = (firstByteOfNextNALUnit&0x60)>>5;
00696 u_int8_t next_nal_unit_type = firstByteOfNextNALUnit&0x1F;
00697 if (next_nal_unit_type >= 6) {
00698
00699 #ifdef DEBUG
00700 fprintf(stderr, "\t(The next NAL unit is not a VCL)\n");
00701 #endif
00702 thisNALUnitEndsAccessUnit = True;
00703 } else {
00704
00705
00706 Boolean IdrPicFlag = nal_unit_type == 5;
00707 Boolean next_IdrPicFlag = next_nal_unit_type == 5;
00708 if (next_IdrPicFlag != IdrPicFlag) {
00709
00710 #ifdef DEBUG
00711 fprintf(stderr, "\t(IdrPicFlag differs in value)\n");
00712 #endif
00713 thisNALUnitEndsAccessUnit = True;
00714 } else if (next_nal_ref_idc != nal_ref_idc && next_nal_ref_idc*nal_ref_idc == 0) {
00715
00716 #ifdef DEBUG
00717 fprintf(stderr, "\t(nal_ref_idc differs in value with one of the nal_ref_idc values being equal to 0)\n");
00718 #endif
00719 thisNALUnitEndsAccessUnit = True;
00720 } else if ((nal_unit_type == 1 || nal_unit_type == 2 || nal_unit_type == 5)
00721 && (next_nal_unit_type == 1 || next_nal_unit_type == 2 || next_nal_unit_type == 5)) {
00722
00723
00724
00725
00726 unsigned frame_num, pic_parameter_set_id, idr_pic_id;
00727 Boolean field_pic_flag, bottom_field_flag;
00728 analyze_slice_header(fStartOfFrame + fOutputStartCodeSize, fTo, nal_unit_type,
00729 frame_num, pic_parameter_set_id, idr_pic_id, field_pic_flag, bottom_field_flag);
00730
00731
00732 #ifdef DEBUG
00733 fprintf(stderr, " Next NAL unit's slice_header:\n");
00734 #endif
00735 u_int8_t next_slice_header[NUM_NEXT_SLICE_HEADER_BYTES_TO_ANALYZE];
00736 testBytes(next_slice_header, sizeof next_slice_header);
00737 unsigned next_frame_num, next_pic_parameter_set_id, next_idr_pic_id;
00738 Boolean next_field_pic_flag, next_bottom_field_flag;
00739 analyze_slice_header(next_slice_header, &next_slice_header[sizeof next_slice_header], next_nal_unit_type,
00740 next_frame_num, next_pic_parameter_set_id, next_idr_pic_id, next_field_pic_flag, next_bottom_field_flag);
00741
00742 if (next_frame_num != frame_num) {
00743
00744 #ifdef DEBUG
00745 fprintf(stderr, "\t(frame_num differs in value)\n");
00746 #endif
00747 thisNALUnitEndsAccessUnit = True;
00748 } else if (next_pic_parameter_set_id != pic_parameter_set_id) {
00749
00750 #ifdef DEBUG
00751 fprintf(stderr, "\t(pic_parameter_set_id differs in value)\n");
00752 #endif
00753 thisNALUnitEndsAccessUnit = True;
00754 } else if (next_field_pic_flag != field_pic_flag) {
00755
00756 #ifdef DEBUG
00757 fprintf(stderr, "\t(field_pic_flag differs in value)\n");
00758 #endif
00759 thisNALUnitEndsAccessUnit = True;
00760 } else if (next_bottom_field_flag != bottom_field_flag) {
00761
00762 #ifdef DEBUG
00763 fprintf(stderr, "\t(bottom_field_flag differs in value)\n");
00764 #endif
00765 thisNALUnitEndsAccessUnit = True;
00766 } else if (next_IdrPicFlag == 1 && next_idr_pic_id != idr_pic_id) {
00767
00768
00769 #ifdef DEBUG
00770 fprintf(stderr, "\t(IdrPicFlag is equal to 1 for both and idr_pic_id differs in value)\n");
00771 #endif
00772 thisNALUnitEndsAccessUnit = True;
00773 }
00774 }
00775 }
00776 }
00777 }
00778
00779 if (thisNALUnitEndsAccessUnit) {
00780 #ifdef DEBUG
00781 fprintf(stderr, "*****This NAL unit ends the current access unit*****\n");
00782 #endif
00783 usingSource()->fPictureEndMarker = True;
00784 ++usingSource()->fPictureCount;
00785
00786
00787 struct timeval& nextPT = usingSource()->fNextPresentationTime;
00788 nextPT = usingSource()->fPresentationTime;
00789 double nextFraction = nextPT.tv_usec/1000000.0 + 1/usingSource()->fFrameRate;
00790 unsigned nextSecsIncrement = (long)nextFraction;
00791 nextPT.tv_sec += (long)nextSecsIncrement;
00792 nextPT.tv_usec = (long)((nextFraction - nextSecsIncrement)*1000000);
00793 }
00794 setParseState();
00795
00796 return curFrameSize();
00797 } catch (int ) {
00798 #ifdef DEBUG
00799 fprintf(stderr, "H264VideoStreamParser::parse() EXCEPTION (This is normal behavior - *not* an error)\n");
00800 #endif
00801 return 0;
00802 }
00803 }