예제 #1
0
//---------------------------------------------------------------------------------------------
int32_t BitMessage::read_uint8() const
{
  	return (int32_t)read_bits(8);

}
예제 #2
0
/*!
 * \param *dc The current DecodingContext.
 * \param mbAddr The current macroblock address.
 * \return 0 if macroblock decoding fail, 1 otherwise.
 *
 * This function extract one macroblock from the bitstream, handle intra/inter
 * prediction for its blocks.
 */
int macroblock_layer(DecodingContext_t *dc, const int mbAddr)
{
    TRACE_INFO(MB, "<> " BLD_GREEN "macroblock_layer(" CLR_RESET "%i" BLD_GREEN ")\n" CLR_RESET, mbAddr);
    int retcode = FAILURE;

    // Macroblock allocation
    ////////////////////////////////////////////////////////////////////////////

    dc->mb_array[mbAddr] = (Macroblock_t*)calloc(1, sizeof(Macroblock_t));

    if (dc->mb_array[mbAddr] == NULL)
    {
        TRACE_ERROR(MB, "Unable to alloc new macroblock!\n");
    }
    else
    {
        // Set macroblock address
        dc->mb_array[mbAddr]->mbAddr = mbAddr;

        // Shortcuts
        pps_t *pps = dc->pps_array[dc->active_slice->pic_parameter_set_id];
        sps_t *sps = dc->sps_array[pps->seq_parameter_set_id];
        slice_t *slice = dc->active_slice;
        Macroblock_t *mb = dc->mb_array[mbAddr];

        // Macroblock decoding
        ////////////////////////////////////////////////////////////////////////

#if ENABLE_DEBUG
        mb->mbFileAddrStart = bitstream_get_absolute_bit_offset(dc->bitstr);
#endif // ENABLE_DEBUG

        deriv_macroblockneighbours_availability(dc, mbAddr);
        MbPosition(mb, sps);

        if (pps->entropy_coding_mode_flag)
            mb->mb_type = read_ae(dc, SE_mb_type);
        else
            mb->mb_type = read_ue(dc->bitstr);

        mb->MbPartPredMode[0] = MbPartPredMode(mb, slice->slice_type, 0);
        mb->NumMbPart = NumMbPart(slice->slice_type, mb->mb_type);

        if (mb->mb_type == I_PCM)
        {
#if ENABLE_IPCM
            TRACE_3(MB, "---- macroblock_layer - I PCM macroblock\n");

            while (bitstream_check_alignment(dc->bitstr) == false)
            {
                if (read_bit(dc->bitstr) != 0) // pcm_alignment_zero_bit
                {
                    TRACE_ERROR(MB, "  Error while reading pcm_alignment_zero_bit: must be 0!\n");
                    return FAILURE;
                }
            }

            // CABAC initialization process //FIXME needed? See 'ITU-T H.264' recommendation 9.3.1.2
            initCabacDecodingEngine(dc);

            int i = 0;
            for (i = 0; i < 256; i++)
            {
                mb->pcm_sample_luma[i] = (uint8_t)read_bits(dc->bitstr, sps->BitDepthY);
            }

            // CABAC initialization process //FIXME needed? See 'ITU-T H.264' recommendation 9.3.1.2
            initCabacDecodingEngine(dc);

            for (i = 0; i < 2 * sps->MbWidthC * sps->MbHeightC; i++)
            {
                mb->pcm_sample_chroma[i] = (uint8_t)read_bits(dc->bitstr, sps->BitDepthC);
            }

            // CABAC initialization process //FIXME needed? See 'ITU-T H.264' recommendation 9.3.1.2
            initCabacDecodingEngine(dc);
#else // ENABLE_IPCM
            TRACE_ERROR(MB, "I_PCM decoding is currently disabled!\n");
            return UNSUPPORTED;
#endif // ENABLE_IPCM
        }
        else
        {
#if ENABLE_INTER_PRED
            bool noSubMbPartSizeLessThan8x8Flag = true;

            if (mb->mb_type != I_NxN &&
                mb->MbPartPredMode[0] != Intra_16x16 &&
                mb->NumMbPart == 4)
            {
                TRACE_3(MB, "---- macroblock_layer - mb partition & related\n");

                int mbPartIdx = 0;
                for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
                {
                    if (mb->sub_mb_type[mbPartIdx] != B_Direct_8x8)
                    {
                        if (NumSubMbPart(slice->slice_type, mb->sub_mb_type[mbPartIdx]) > 1)
                        {
                            noSubMbPartSizeLessThan8x8Flag = false;
                        }
                    }
                    else if (sps->direct_8x8_inference_flag == false)
                    {
                        noSubMbPartSizeLessThan8x8Flag = false;
                    }
                }

                // Read sub macroblock prediction mode
                sub_mb_pred(dc, mb->mb_type, mb->sub_mb_type);
            }
            else
#endif // ENABLE_INTER_PRED
            {
                TRACE_3(MB, "---- macroblock_layer - transform_size_8x8_flag & prediction modes\n");

                if (pps->transform_8x8_mode_flag == true && mb->mb_type == I_NxN)
                {
                    if (pps->entropy_coding_mode_flag)
                        mb->transform_size_8x8_flag = read_ae(dc, SE_transform_size_8x8_flag);
                    else
                        mb->transform_size_8x8_flag = read_bit(dc->bitstr);

                    // Need to update MbPartPredMode in order to detect I_8x8 prediction mode
                    mb->MbPartPredMode[0] = MbPartPredMode(mb, slice->slice_type, 0);
                }

                // Read macroblock prediction mode
                mb_pred(dc, mb);
            }

            if (mb->MbPartPredMode[0] != Intra_16x16)
            {
                TRACE_3(MB, "---- macroblock_layer - coded block pattern & transform_size_8x8_flag\n");

                if (pps->entropy_coding_mode_flag)
                    mb->coded_block_pattern = read_ae(dc, SE_coded_block_pattern);
                else
                    mb->coded_block_pattern = read_me(dc->bitstr, sps->ChromaArrayType, dc->IdrPicFlag);

                mb->CodedBlockPatternLuma = mb->coded_block_pattern % 16;
                mb->CodedBlockPatternChroma = mb->coded_block_pattern / 16;
#if ENABLE_INTER_PRED
                if (mb->CodedBlockPatternLuma > 0 &&
                    pps->transform_8x8_mode_flag == true &&
                    mb->mb_type != I_NxN &&
                    noSubMbPartSizeLessThan8x8Flag == true &&
                    (mb->mb_type != B_Direct_16x16 || sps->direct_8x8_inference_flag == true))
                {
                    if (pps->entropy_coding_mode_flag)
                        mb->transform_size_8x8_flag = read_ae(dc, SE_transform_size_8x8_flag);
                    else
                        mb->transform_size_8x8_flag = read_bit(dc->bitstr);

                    // Need to update MbPartPredMode in order to account for I_8x8 prediction mode
                    if (transform_size_8x8_flag)
                        mb->MbPartPredMode[0] = MbPartPredMode(mb, slice->slice_type, 0);
                }
#endif // ENABLE_INTER_PRED
            }

            if (mb->CodedBlockPatternLuma > 0 ||
                mb->CodedBlockPatternChroma > 0 ||
                mb->MbPartPredMode[0] == Intra_16x16)
            {
                TRACE_3(MB, "---- macroblock_layer - quantization parameter & residual datas\n");

                // Read QP delta
                if (pps->entropy_coding_mode_flag)
                    mb->mb_qp_delta = read_ae(dc, SE_mb_qp_delta);
                else
                    mb->mb_qp_delta = read_se(dc->bitstr);

                // Parse the residual coefficients
                ////////////////////////////////////////////////////////////////

                // Luma levels
                residual_luma(dc, 0, 15);

                // Chroma levels
                residual_chroma(dc, 0, 15);
            }
            else
            {
                TRACE_3(MB, "---- macroblock_layer - No residual datas to decode in this macroblock\n");
            }

            // Compute luma Quantization Parameters
            if (mb->mb_qp_delta)
                mb->QPY = ((slice->QPYprev + mb->mb_qp_delta + 52 + sps->QpBdOffsetY*2) % (52 + sps->QpBdOffsetY)) - sps->QpBdOffsetY;
            else
                mb->QPY = slice->QPYprev;

            mb->QPprimeY = mb->QPY + sps->QpBdOffsetY;
            slice->QPYprev = mb->QPY;

            // Set Transform Bypass Mode
            if (sps->qpprime_y_zero_transform_bypass_flag == true && mb->QPprimeY == 0)
                mb->TransformBypassModeFlag = true;

            // Prediction process (include quantization and transformation stages)
            ////////////////////////////////////////////////////////////////

            if (dc->IdrPicFlag)
            {
                retcode = intra_prediction_process(dc, mb);
            }
            else
            {
                retcode = inter_prediction_process(dc, mb);
            }

            // Print macroblock(s) header and block data ?
            ////////////////////////////////////////////////////////////////

#if ENABLE_DEBUG
            mb->mbFileAddrStop = bitstream_get_absolute_bit_offset(dc->bitstr) - 1;

            int frame_debug_range[2] = {-1, -1}; // Range of (idr) frame(s) to debug/analyse
            int mb_debug_range[2] = {-1, -1}; // Range of macroblock(s) to debug/analyse

            if (dc->idrCounter >= frame_debug_range[0] && dc->idrCounter <= frame_debug_range[1])
            {
                if (mb->mbAddr >= mb_debug_range[0] && mb->mbAddr <= mb_debug_range[1])
                {
                    print_macroblock_layer(dc, mb);
                    print_macroblock_pixel_residual(mb);
                    print_macroblock_pixel_predicted(mb);
                    print_macroblock_pixel_final(mb);
                }
            }
#endif // ENABLE_DEBUG
        }

        TRACE_3(MB, "---- macroblock_layer - the end\n\n");
    }

    return retcode;
}
예제 #3
0
파일: itsex.c 프로젝트: GCrean/libxmp
int itsex_decompress8(HIO_HANDLE *src, uint8 *dst, int len, int it215)
{
	uint32 size = 0;
	uint32 block_count = 0;
	uint32 bitbuf = 0;
	int bitnum = 0;
	uint8 left = 0, temp = 0, temp2 = 0;
	uint32 d, pos;

	while (len) {
		if (!block_count) {
			block_count = 0x8000;
			size = hio_read16l(src);
			left = 9;
			temp = temp2 = 0;
			bitbuf = bitnum = 0;
		}

		d = block_count;
		if (d > len)
			d = len;

		/* Unpacking */
		pos = 0;
		do {
			uint16 bits = read_bits(src, &bitbuf, &bitnum, left);
			if (hio_eof(src))
				return -1;

			if (left < 7) {
				uint32 i = 1 << (left - 1);
				uint32 j = bits & 0xffff;
				if (i != j)
					goto unpack_byte;
				bits = (read_bits(src, &bitbuf, &bitnum, 3)
								+ 1) & 0xff;
				if (hio_eof(src))
					return -1;

				left = ((uint8)bits < left) ?  (uint8)bits :
						(uint8)((bits + 1) & 0xff);
				goto next;
			}

			if (left < 9) {
				uint16 i = (0xff >> (9 - left)) + 4;
				uint16 j = i - 8;

				if ((bits <= j) || (bits > i))
					goto unpack_byte;

				bits -= j;
				left = ((uint8)(bits & 0xff) < left) ?
						(uint8)(bits & 0xff) :
						(uint8)((bits + 1) & 0xff);
				goto next;
			}

			if (left >= 10)
				goto skip_byte;

			if (bits >= 256) {
				left = (uint8) (bits + 1) & 0xff;
				goto next;
			}

		    unpack_byte:
			if (left < 8) {
				uint8 shift = 8 - left;
				signed char c = (signed char)(bits << shift);
				c >>= shift;
				bits = (uint16) c;
			}
			bits += temp;
			temp = (uint8)bits;
			temp2 += temp;
			dst[pos] = it215 ? temp2 : temp;

		    skip_byte:
			pos++;

		    next:
			/* if (slen <= 0)
				return -1 */;
		} while (pos < d);
예제 #4
0
파일: ps.c 프로젝트: seanvk/MiniVideo
/*!
 * \brief Parse a program stream directory structure.
 * \param *bitstr A bitstream.
 * \param *packet A program stream directory structure.
 * \return retcode 1 if succeed, 0 otherwise.
 *
 * H.222 / 2.5.5 Program Stream directory.
 */
static int parse_program_stream_directory(Bitstream_t *bitstr, ProgramStreamDirectory_t *packet)
{
    TRACE_INFO(MPS, BLD_GREEN "parse_program_stream_directory()" CLR_RESET " @ %i\n", bitstream_get_absolute_byte_offset(bitstr) - 4);
    int retcode = SUCCESS;
    int i = 0;

    packet->packet_start_code_prefix = 0x000001;
    packet->directory_stream_id = 0xFF;
    packet->PES_packet_length = read_bits(bitstr, 16);
    packet->number_of_access_units = read_bits(bitstr, 15);
    MARKER_BIT

    packet->prev_directory_offset = read_bits(bitstr, 15) << 30;
    MARKER_BIT
    packet->prev_directory_offset += read_bits(bitstr, 15) << 15;
    MARKER_BIT
    packet->prev_directory_offset += read_bits(bitstr, 15);
    MARKER_BIT

    packet->next_directory_offset = read_bits(bitstr, 15) << 30;
    MARKER_BIT
    packet->next_directory_offset += read_bits(bitstr, 15) << 15;
    MARKER_BIT
    packet->next_directory_offset += read_bits(bitstr, 15);
    MARKER_BIT

    for (i = 0; i < packet->number_of_access_units; i++)
    {
        // TODO stack it?
        packet->packet_stream_id = read_bits(bitstr, 8);
        packet->PES_header_position_offset_sign = read_bit(bitstr);

        packet->PES_header_position_offset = read_bits(bitstr, 14) << 30;
        MARKER_BIT
        packet->PES_header_position_offset += read_bits(bitstr, 15) << 15;
        MARKER_BIT
        packet->PES_header_position_offset += read_bits(bitstr, 15);
        MARKER_BIT

        packet->reference_offset = read_bits(bitstr, 16);
        MARKER_BIT
        int reserved1 = read_bits(bitstr, 3);

        packet->PTS = read_bits(bitstr, 3) << 30;
        MARKER_BIT
        packet->PTS += read_bits(bitstr, 15) << 15;
        MARKER_BIT
        packet->PTS += read_bits(bitstr, 15);
        MARKER_BIT

        packet->byes_to_read = read_bits(bitstr, 15) << 15;
        MARKER_BIT
        packet->byes_to_read += read_bits(bitstr, 8);
        MARKER_BIT

        packet->intra_coded_indicator = read_bit(bitstr);
        packet->coding_parameters_indicator = read_bits(bitstr, 2);
        int reserved2 = read_bits(bitstr, 4);
    }

    return retcode;
}
예제 #5
0
파일: ps.c 프로젝트: seanvk/MiniVideo
/*!
 * \brief Parse a pack header structure.
 * \param *bitstr The bitstream to use.
 * \param *pack_header A pointer to a pack_header structure.
 * \param *system_header A pointer to a system_header structure.
 * \return retcode 1 if succeed, 0 otherwise.
 *
 * This parser is based on the 'ISO/IEC 13818-1' international standard, part 1:
 * 'Transmission multiplexing and synchronization'.
 */
static int parse_pack_header(Bitstream_t *bitstr, PackHeader_t *pack_header, SystemHeader_t *system_header)
{
    TRACE_INFO(MPS, BLD_GREEN "parse_pack_header()" CLR_RESET " @ %i\n", bitstream_get_absolute_byte_offset(bitstr) - 4);
    int retcode = SUCCESS;
    int i = 0;

    pack_header->pack_start_code = PES_PACK_HEADER;

    if (read_bits(bitstr, 2) != 1)
    {
        TRACE_ERROR(MPS, "wrong 'marker_bit'\n");
        return FAILURE;
    }

    pack_header->system_clock_reference_base = read_bits(bitstr, 3) << 30;
    MARKER_BIT
    pack_header->system_clock_reference_base += read_bits(bitstr, 15) << 15;
    MARKER_BIT
    pack_header->system_clock_reference_base += read_bits(bitstr, 15);
    MARKER_BIT
    pack_header->system_clock_reference_extension = read_bits(bitstr, 9);
    MARKER_BIT
    pack_header->program_mux_rate = read_bits(bitstr, 22);
    MARKER_BIT
    MARKER_BIT
    int reserved = read_bits(bitstr, 5);

    pack_header->pack_stuffing_length = read_bits(bitstr, 3);

    // Stuffing
    for (i = 0; i < pack_header->pack_stuffing_length; i++)
    {
        if (read_bits(bitstr, 8) != 0xFF)
        {
            TRACE_ERROR(MPS, "Wrong 'stuffing_byte'\n");
            return FAILURE;
        }
    }

    // System header
    if (next_bits(bitstr, 32) == PES_SYSTEM_HEADER)
    {
        TRACE_INFO(MPS, BLD_GREEN "parse_system_header()" CLR_RESET " @ %i\n", bitstream_get_absolute_byte_offset(bitstr) - 4);
        skip_bits(bitstr, 32);

        system_header->header_length = read_bits(bitstr, 16);
        MARKER_BIT
        system_header->rate_bound = read_bits(bitstr, 22);
        MARKER_BIT
        system_header->audio_bound = read_bits(bitstr, 6);
        system_header->fixed_flag = read_bits(bitstr, 1);
        system_header->CSPS_flag = read_bits(bitstr, 1);
        system_header->system_audio_lock_flag = read_bits(bitstr, 1);
        system_header->system_video_lock_flag = read_bits(bitstr, 1);
        MARKER_BIT
        system_header->video_bound = read_bits(bitstr, 5);
        system_header->packet_rate_restriction_flag = read_bits(bitstr, 1);

        int reserved_bits = read_bits(bitstr, 7);

        // stack it?
        while (next_bit(bitstr) == 1)
        {
            system_header->stream_id = read_bits(bitstr, 8);
            MARKER_BIT
            MARKER_BIT
            system_header->PSTD_buffer_bound_scale = read_bits(bitstr, 1);
            system_header->PSTD_buffer_size_bound = read_bits(bitstr, 13);
        }
    }
    else
    {
        TRACE_2(MPS, " > No system_header()\n");
    }

    return retcode;
}
예제 #6
0
// Return TRUE if the data parsing finished, FALSE otherwise.
// estream->pos is advanced. Data is only processed if esstream->error
// is FALSE, parsing can set esstream->error to TRUE.
static int gop_header(struct lib_ccx_ctx *ctx, struct bitstream *esstream, struct cc_subtitle *sub)
{
    dbg_print(CCX_DMT_VERBOSE, "GOP header\n");

    if (esstream->error || esstream->bitsleft <= 0)
        return 0;

    // We only get here after seeing that start code
    if (read_u32(esstream) != 0xB8010000) // LSB first (0x000001B8)
        fatal(CCX_COMMON_EXIT_BUG_BUG, "Impossible!");

    unsigned drop_frame_flag = (unsigned) read_bits(esstream,1);
    struct gop_time_code gtc;
    gtc.time_code_hours = (int) read_bits(esstream,5);
    gtc.time_code_minutes = (int) read_bits(esstream,6);
    skip_bits(esstream,1); // Marker bit
    gtc.time_code_seconds = (int) read_bits(esstream,6);
    gtc.time_code_pictures = (int) read_bits(esstream,6);
    gtc.inited = 1;
    calculate_ms_gop_time(&gtc);

    if (esstream->bitsleft < 0)
        return 0;

    if (gop_accepted(&gtc))
    {
        // Do GOP padding during GOP header. The previous GOP and all
        // included captions are written. Use the current GOP time to
        // do the padding.

        // Flush buffered cc blocks before doing the housekeeping
        if (has_ccdata_buffered)
        {
            process_hdcc(ctx, sub);
        }

        // Last GOPs pulldown frames
        if ((current_pulldownfields>0) != (pulldownfields>0))
        {
            current_pulldownfields = pulldownfields;
            dbg_print(CCX_DMT_VERBOSE, "Pulldown: %s", (pulldownfields ? "on" : "off"));
            if (pulldownfields)
                dbg_print(CCX_DMT_VERBOSE, " - %u fields in last GOP", pulldownfields);
            dbg_print(CCX_DMT_VERBOSE, "\n");
        }
        pulldownfields = 0;

        // Report synchronization jumps between GOPs. Warn if there
        // are 20% or more deviation.
        if ( (ccx_options.debug_mask & CCX_DMT_TIME)
             && ((gtc.ms - gop_time.ms // more than 20% longer
                  > ctx->frames_since_last_gop*1000.0/current_fps*1.2)
                 ||
                 (gtc.ms - gop_time.ms // or 20% shorter
                  < ctx->frames_since_last_gop*1000.0/current_fps*0.8))
             && first_gop_time.inited )
        {
            mprint("\rWarning: Jump in GOP timing.\n");
            mprint("  (old) %s",
                   print_mstime(gop_time.ms));
            mprint("  +  %s (%uF)",
                   print_mstime((LLONG) (ctx->frames_since_last_gop
                                      *1000.0/current_fps)),
                   ctx->frames_since_last_gop);
            mprint("  !=  (new) %s\n",
                   print_mstime(gtc.ms));
        }

        if (first_gop_time.inited == 0)
        {
            first_gop_time = gtc;

            // It needs to be "+1" because the frame count starts at 0 and we
            // need the length of all frames.
            if ( total_frames_count == 0 )
            {   // If this is the first frame there cannot be an offset
                fts_fc_offset = 0;
                // first_gop_time.ms stays unchanged
            }
            else
            {
                fts_fc_offset = (LLONG) ((total_frames_count+1)
                                      *1000.0/current_fps);
                // Compensate for those written before
                first_gop_time.ms -= fts_fc_offset;
            }

            dbg_print(CCX_DMT_TIME, "\nFirst GOP time: %02u:%02u:%02u:%03u %+lldms\n",
                    gtc.time_code_hours,
                    gtc.time_code_minutes, gtc.time_code_seconds,
                    (unsigned) (1000.0*gtc.time_code_pictures/current_fps),
                    fts_fc_offset);
        }

        gop_time = gtc;

        ctx->frames_since_last_gop=0;
        // Indicate that we read a gop header (since last frame number 0)
        ctx->saw_gop_header = 1;

        // If we use GOP timing, reconstruct the PTS from the GOP
        if (ccx_options.use_gop_as_pts==1)
        {
            current_pts = gtc.ms*(MPEG_CLOCK_FREQ/1000);
            if (pts_set==0)
                pts_set=1;
            current_tref = 0;
            frames_since_ref_time = 0;
            set_fts();
            fts_at_gop_start = get_fts_max();
        }
        else
        {
            // FIXME: Wrong when PTS are not increasing but are identical
            // troughout the GOP and then jump to the next time for the
            // next GOP.
            // This effect will also lead to captions being one GOP early
            // for DVD captions.
            fts_at_gop_start = get_fts_max() + (LLONG) (1000.0/current_fps);
        }

        if (ccx_options.debug_mask & CCX_DMT_TIME)
        {
            dbg_print(CCX_DMT_TIME, "\nNew GOP:\n");
            dbg_print(CCX_DMT_TIME, "\nDrop frame flag: %u:\n", drop_frame_flag);
            print_debug_timing();
        }
    }

    return 1;
}
예제 #7
0
void H264_decodePPS(int v, u_char *b, int len) {

  H264_PPS pps = {0,};

  uint8_t nal_unit_type = b[3]&0x1F;

  bitdata data = {0,};
  data.data = (byte*)(b+4);
  data.data_len = remove_0x03(b+4, len-4);
  data.cur_bit = -1;

  read_exp_golomb(&data, &pps.pic_parameter_set_id);
  read_exp_golomb(&data, &pps.seq_parameter_set_id);
  read_bit(&data, &pps.entropy_coding_mode_flag);
  read_bit(&data, &pps.pic_order_present_flag);
  
  read_exp_golomb(&data, &pps.num_slice_groups_minus1);
  if (pps.num_slice_groups_minus1 > 0) {

    read_exp_golomb(&data, &pps.slice_group_map_type);
    switch (pps.slice_group_map_type) {
      case 0: {
        uint32_t i;
        for (i = 0; i <= pps.num_slice_groups_minus1; ++i) {
          uint32_t run_length_minus1;
          read_exp_golomb(&data, &run_length_minus1);
        }
      } break;
      case 2: {
        uint32_t i;
        for (i = 0; i < pps.num_slice_groups_minus1; ++i) {
          uint32_t top_left, bottom_right;
          read_exp_golomb(&data, &top_left);
          read_exp_golomb(&data, &bottom_right);
        }
      } break;
      case 3:
      case 4:
      case 5: {
        read_bit(&data, &pps.slice_group_change_direction_flag);
        read_exp_golomb(&data, &pps.slice_group_change_rate_minus1);
      } break;
      case 6: {
        uint32_t i, size = (uint32_t)ceil(log2(pps.num_slice_groups_minus1+1));
        read_exp_golomb(&data, &pps.pic_size_in_map_units_minus1);
        for (i = 0; i <= pps.pic_size_in_map_units_minus1; ++i) {
          uint32_t slice_group_id;
          read_bits(&data, size, &slice_group_id);
        }
      } break;
    } // switch (pps.slice_group_map_type)

  } // if (pps.num_slice_groups_minus1 > 0)

  read_exp_golomb(&data, &pps.num_ref_idx_l0_active_minus1);
  read_exp_golomb(&data, &pps.num_ref_idx_l1_active_minus1);
  read_bit(&data, &pps.weighted_pred_flag);
  read_bits(&data, 2, &pps.weighted_bipred_idc);
  read_signed_exp_golomb(&data, &pps.pic_init_qp_minus26);
  read_signed_exp_golomb(&data, &pps.pic_init_qs_minus26);
  read_signed_exp_golomb(&data, &pps.chroma_qp_index_offset);
  read_bit(&data, &pps.deblocking_filter_control_present_flag);
  read_bit(&data, &pps.constrained_intra_pred_flag);
  read_bit(&data, &pps.redundant_pic_cnt_present_flag);

  decoder.pps = pps;

  out_SB_NL(v, "pic_parameter_set_id: ", pps.pic_parameter_set_id);
  out_SB_NL(v, "seq_parameter_set_id: ", pps.seq_parameter_set_id);
  out_SB_NL(v, "entropy_coding_mode_flag: ", pps.entropy_coding_mode_flag);
  out_SB_NL(v, "pic_order_present_flag: ", pps.pic_order_present_flag);

  out_SB_NL(v, "num_slice_groups_minus1: ", pps.num_slice_groups_minus1);
  if (pps.num_slice_groups_minus1 > 0) {
    out_SB_NL(v, "slice_group_map_type: ", pps.slice_group_map_type);
    switch (pps.slice_group_map_type) {
      case 3:
      case 4:
      case 5:
        out_SB_NL(v, "slice_group_change_direction_flag: ", pps.slice_group_change_direction_flag);
        out_SB_NL(v, "slice_group_change_rate_minus1: ", pps.slice_group_change_rate_minus1);
        break;
      case 6:
        out_SB_NL(v, "pic_size_in_map_units_minus1: ", pps.pic_size_in_map_units_minus1);
        break;
    }
  }

  out_SB_NL(v, "num_ref_idx_l0_active_minus1: ", pps.num_ref_idx_l0_active_minus1);
  out_SB_NL(v, "num_ref_idx_l1_active_minus1: ", pps.num_ref_idx_l1_active_minus1);
  out_SB_NL(v, "weighted_pred_flag: ", pps.weighted_pred_flag);
  out_SB_NL(v, "weighted_bipred_idc: ", pps.weighted_bipred_idc);
  out_SLL_NL(v, "pic_init_qp_minus26: ", pps.pic_init_qp_minus26);
  out_SLL_NL(v, "pic_init_qs_minus26: ", pps.pic_init_qs_minus26);
  out_SLL_NL(v, "chroma_qp_index_offset: ", pps.chroma_qp_index_offset);
  out_SB_NL(v, "deblocking_filter_control_present_flag: ", pps.deblocking_filter_control_present_flag);
  out_SB_NL(v, "constrained_intra_pred_flag: ", pps.constrained_intra_pred_flag);
  out_SB_NL(v, "redundant_pic_cnt_present_flag: ", pps.redundant_pic_cnt_present_flag);
}
예제 #8
0
/*!
 * \param *dc The current DecodingContext.
 * \param *slice The current Slice.
 */
static int decodeSliceHeader(DecodingContext_t *dc, slice_t *slice)
{
    TRACE_INFO(SLICE, "> " BLD_GREEN "decodeSliceHeader()\n" CLR_RESET);

    // Slice header decoding
    ////////////////////////////////////////////////////////////////////////////

    slice->first_mb_in_slice = read_ue(dc->bitstr);
    slice->slice_type = read_ue(dc->bitstr);
    slice->pic_parameter_set_id = read_ue(dc->bitstr);

    // Shortcuts
    pps_t *pps = dc->pps_array[slice->pic_parameter_set_id];
    sps_t *sps = dc->sps_array[pps->seq_parameter_set_id];

    if (sps->separate_colour_plane_flag)
    {
        slice->colour_plane_id = read_bits(dc->bitstr, 2);
    }

    slice->frame_num = read_bits(dc->bitstr, sps->log2_max_frame_num_minus4 + 4);

    if (sps->frame_mbs_only_flag == false)
    {
        slice->field_pic_flag = read_bit(dc->bitstr);
        if (slice->field_pic_flag)
        {
            slice->bottom_field_flag = read_bit(dc->bitstr);

            slice->MaxPicNum = sps->MaxFrameNum*2;
            slice->CurrPicNum = slice->frame_num*2 + 1;
        }
        else
        {
            slice->MaxPicNum = sps->MaxFrameNum;
            slice->CurrPicNum = slice->frame_num;
        }
    }

    slice->MbaffFrameFlag = sps->mb_adaptive_frame_field_flag && !slice->field_pic_flag;
    slice->PicHeightInMbs = sps->FrameHeightInMbs / (1 + slice->field_pic_flag);
    slice->PicHeightInSamplesL = slice->PicHeightInMbs * 16;
    slice->PicHeightInSamplesC = slice->PicHeightInMbs * sps->MbHeightC;
    slice->PicSizeInMbs = sps->PicWidthInMbs * slice->PicHeightInMbs;

    if (dc->IdrPicFlag)
    {
        slice->PrevRefFrameNum = 0;
        slice->idr_pic_id = read_ue(dc->bitstr);
    }

    if (sps->pic_order_cnt_type == 0)
    {
        slice->pic_order_cnt_lsb = read_bits(dc->bitstr, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
        if (pps->bottom_field_pic_order_in_frame_present_flag && slice->field_pic_flag == false)
        {
            slice->delta_pic_order_cnt_bottom = read_se(dc->bitstr);
        }
    }
    else if (sps->pic_order_cnt_type == 1 && sps->delta_pic_order_always_zero_flag == false)
    {
        slice->delta_pic_order_cnt[0] = read_se(dc->bitstr);
        if (pps->bottom_field_pic_order_in_frame_present_flag && slice->field_pic_flag == false)
        {
            slice->delta_pic_order_cnt[1] = read_se(dc->bitstr);
        }
    }

    if (pps->redundant_pic_cnt_present_flag)
    {
        slice->redundant_pic_cnt = read_ue(dc->bitstr);
    }

    if (slice->slice_type == 1 || slice->slice_type == 6) // B frame
    {
        TRACE_ERROR(SLICE, ">>> UNSUPPORTED (B frame)\n");
        return UNSUPPORTED;

        slice->direct_spatial_mv_pred_flag = read_bit(dc->bitstr);
    }

    if (slice->slice_type == 0 || slice->slice_type == 5 ||
        slice->slice_type == 3 || slice->slice_type == 8 ||
        slice->slice_type == 1 || slice->slice_type == 6) // P, SP, B frame
    {
        TRACE_ERROR(SLICE, ">>> UNSUPPORTED (P, SP, B frame)\n");
        return UNSUPPORTED;
/*
        slice->num_ref_idx_active_override_flag = read_bit(dc->bitstr);

        if (slice->num_ref_idx_active_override_flag)
        {
            slice->num_ref_idx_l0_active_minus1 = read_ue(dc->bitstr);

            if (slice->slice_type == 1 || slice->slice_type == 6) // B frame
            {
                slice->num_ref_idx_l1_active_minus1 = read_ue(dc->bitstr);
            }
        }
*/
    }

    if (dc->active_nalu->nal_unit_type == 20)
    {
        TRACE_ERROR(SLICE, ">>> UNSUPPORTED (unit_type == 20: MVC extension)\n");
        return UNSUPPORTED;
    }
    else
    {
        // RPLM
        slice->rplm = decodeRPLM(dc, slice);
    }

    if ((pps->weighted_pred_flag == true &&
         (slice->slice_type == 0 || slice->slice_type == 5 ||
          slice->slice_type == 3 || slice->slice_type == 8)) ||
        (pps->weighted_bipred_idc == 1  &&
         (slice->slice_type == 1 || slice->slice_type == 6))) // P, SP, B frame
    {
        // PWT
        slice->pwt = decodePWT(dc, slice);
    }

    if (dc->active_nalu->nal_ref_idc != 0)
    {
        // DRPM
        slice->drpm = decodeDRPM(dc, slice);
    }

    if (pps->entropy_coding_mode_flag == true &&
        ((slice->slice_type != 2 && slice->slice_type != 7) &&
         (slice->slice_type != 4 && slice->slice_type != 9))) // Not I or SI frame
    {
        slice->cabac_init_idc = read_ue(dc->bitstr);
    }

    slice->slice_qp_delta = read_se(dc->bitstr);
    slice->SliceQPY = 26 + pps->pic_init_qp_minus26 + slice->slice_qp_delta;
    slice->QPYprev = slice->SliceQPY; // Set QPYprev value to use it in the first macroblock

    if (slice->slice_type == 3 || slice->slice_type == 8 ||
        slice->slice_type == 4 || slice->slice_type == 9) // SP, SI frame
    {
#if ENABLE_SWITCHING_SLICE
        if (slice->slice_type == 4 || slice->slice_type == 9)
        {
            slice->sp_for_switch_flag = read_bit(dc->bitstr);
        }

        slice->slice_qs_delta = read_se(dc->bitstr);
        slice->SliceQSY = 26 + pps->pic_init_qs_minus26 + slice->slice_qs_delta;
#else /* ENABLE_SWITCHING_SLICE */
        TRACE_ERROR(SLICE, ">>> UNSUPPORTED (slice_type == SP || slice_type == SI)\n");
        return UNSUPPORTED;
#endif /* ENABLE_SWITCHING_SLICE */
    }

    if (pps->deblocking_filter_control_present_flag)
    {
        slice->disable_deblocking_filter_idc = read_ue(dc->bitstr);
        if (slice->disable_deblocking_filter_idc != 1)
        {
            slice->slice_alpha_c0_offset_div2 = read_se(dc->bitstr);
            slice->slice_beta_offset_div2 = read_se(dc->bitstr);

            slice->FilterOffsetA = slice->slice_alpha_c0_offset_div2 << 1;
            slice->FilterOffsetB = slice->slice_beta_offset_div2 << 1;
        }
    }

    if (pps->num_slice_groups_minus1 > 0 && pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5)
    {
        TRACE_ERROR(SLICE, ">>> UNSUPPORTED (FMO)\n");
        return UNSUPPORTED;
    }

    // Check content
    return checkSliceHeader(dc);
}
예제 #9
0
// Return TRUE if the data parsing finished, FALSE otherwise.
// estream->pos is advanced. Data is only processed if esstream->error
// is FALSE, parsing can set esstream->error to TRUE.
static int sequence_header(struct lib_cc_decode *ctx, struct bitstream *esstream)
{
	debug("Sequence header\n");

	if (esstream->error || esstream->bitsleft <= 0)
		return 0;

	// We only get here after seeing that start code
	if (read_u32(esstream) != 0xB3010000) // LSB first (0x000001B3)
		fatal(CCX_COMMON_EXIT_BUG_BUG, "sequence_header: read_u32(esstream) != 0xB3010000. Please file a bug report in GitHub.\n");

	unsigned hor_size = (unsigned) read_bits(esstream,12);
	unsigned vert_size = (unsigned) read_bits(esstream,12);
	unsigned aspect_ratio = (unsigned) read_bits(esstream,4);
	unsigned frame_rate = (unsigned) read_bits(esstream,4);

#if 0
	ctx->freport.width = hor_size;
	ctx->freport.height = vert_size;
	ctx->freport.aspect_ratio = aspect_ratio;
	ctx->freport.frame_rate = frame_rate;
#endif

	// Discard some information
	read_bits(esstream, 18+1+10+1);

	// load_intra_quantiser_matrix
	if (read_bits(esstream,1))
		skip_bits(esstream, 8*64);
	// load_non_intra_quantiser_matrix
	if (read_bits(esstream,1))
		skip_bits(esstream, 8*64);

	if (esstream->bitsleft < 0)
		return 0;

	// If we got the whole sequence, process
	if (hor_size!= ctx->current_hor_size ||
		vert_size!= ctx->current_vert_size ||
		aspect_ratio!=ctx->current_aspect_ratio ||
		frame_rate!= ctx->current_frame_rate)
	{
		// If horizontal/vertical size, framerate and/or aspect
		// ratio are ilegal, we discard the
		// whole sequence info.
		if (vert_size >= 288 && vert_size <= 1088 &&
				hor_size >= 352 && hor_size <= 1920 &&
				(hor_size*100) / vert_size >= (352*100)/576 && // The weird *100 is to avoid using floats
				hor_size / vert_size <= 2 &&
				frame_rate>0 && frame_rate<9 &&
				aspect_ratio>0 && aspect_ratio<5)
		{
			mprint ("\n\nNew video information found");
			mprint ("\n");
			mprint ("[%u * %u] [AR: %s] [FR: %s]",
					hor_size,vert_size,
					aspect_ratio_types[aspect_ratio],
					framerates_types[frame_rate]);
			// No newline, force the output of progressive info in picture
			// info part.
			ctx->current_progressive_sequence = 2;

			ctx->current_hor_size     = hor_size;
			ctx->current_vert_size    = vert_size;
			ctx->current_aspect_ratio = aspect_ratio;
			ctx->current_frame_rate=frame_rate;
			current_fps = framerates_values[ctx->current_frame_rate];
			activity_video_info (hor_size,vert_size,
					aspect_ratio_types[aspect_ratio],
					framerates_types[frame_rate]);
		}
		else
		{
			debug("\nInvalid sequence header:\n");
			debug("V: %u H: %u FR: %u AS: %u\n",
					vert_size, hor_size, frame_rate, aspect_ratio);
			esstream->error = 1;
			return 0;
		}
	}

	// Read complete
	return 1;
}
예제 #10
0
static int read_bit(BitStreamReader *reader)
{
	return read_bits(reader, 1);
}
예제 #11
0
파일: pm2_decoder.c 프로젝트: djdron/zxtune
static int read_code_tree(LHAPM2Decoder *decoder)
{
	uint8_t code_lengths[31];
	int num_codes, min_code_length, length_bits, val;
	unsigned int i;

	// Read the number of codes in the tree.

	num_codes = read_bits(&decoder->bit_stream_reader, 5);

	// Read min_code_length, which is used as an offset.

	min_code_length = read_bits(&decoder->bit_stream_reader, 3);

	if (min_code_length < 0 || num_codes < 0) {
		return 0;
	}

	// Store flag variable indicating whether we want to read
	// the offset tree as well.

	decoder->need_offset_tree
	    = num_codes >= 10
	   && !(num_codes == 29 && min_code_length == 0);

	// Minimum length of zero means a tree containing a single code.

	if (min_code_length == 0) {
		set_tree_single(decoder->code_tree, num_codes - 1);
		return 1;
	}

	// How many bits are used to represent each table entry?

	length_bits = read_bits(&decoder->bit_stream_reader, 3);

	if (length_bits < 0) {
		return 0;
	}

	// Read table of code lengths:

	for (i = 0; i < (unsigned int) num_codes; ++i) {

		// Read a table entry.  A value of zero represents an
		// unused code.  Otherwise the value represents
		// an offset from the minimum length (previously read).

		val = read_bits(&decoder->bit_stream_reader,
		                (unsigned int) length_bits);

		if (val < 0) {
			return 0;
		} else if (val == 0) {
			code_lengths[i] = 0;
		} else {
			code_lengths[i] = (uint8_t) (min_code_length + val - 1);
		}
	}

	// Build the tree.

	build_tree(decoder->code_tree, sizeof(decoder->code_tree),
	           code_lengths, (unsigned int) num_codes);

	return 1;
}
예제 #12
0
//---------------------------------------------------------------------------------------------
float BitMessage::read_float() const
{
	float value;
	*reinterpret_cast<int*>(&value) = read_bits(32);
	return value;  
}
예제 #13
0
//---------------------------------------------------------------------------------------------
int32_t BitMessage::read_int32() const
{
	return (int32_t)read_bits(32);
}
예제 #14
0
//---------------------------------------------------------------------------------------------
int32_t BitMessage::read_uint16() const
{
	return (int32_t)read_bits(16);  
}
예제 #15
0
int
h264_decode_seq_parameter_set(elementary_stream_t *st, bitstream_t *bs)
{
  int profile_idc, level_idc, poc_type;
  unsigned int sps_id, tmp, i, width, height;
  int cbpsize = -1;
  h264_private_t *p;

  if((p = st->es_priv) == NULL)
    p = st->es_priv = calloc(1, sizeof(h264_private_t));

  profile_idc= read_bits(bs, 8);
  read_bits1(bs);   //constraint_set0_flag
  read_bits1(bs);   //constraint_set1_flag
  read_bits1(bs);   //constraint_set2_flag
  read_bits1(bs);   //constraint_set3_flag
  read_bits(bs, 4); // reserved
  level_idc= read_bits(bs, 8);
  sps_id= read_golomb_ue(bs);


  i = 0;
  while(h264_lev2cpbsize[i][0] != -1) {
    if(h264_lev2cpbsize[i][0] >= level_idc) {
      cbpsize = h264_lev2cpbsize[i][1];
      break;
    }
    i++;
  }
  if(cbpsize < 0)
    return -1;

  p->sps[sps_id].cbpsize = cbpsize * 125; /* Convert from kbit to bytes */


  if(profile_idc >= 100){ //high profile
    if(read_golomb_ue(bs) == 3) //chroma_format_idc
      read_bits1(bs);  //residual_color_transform_flag
    read_golomb_ue(bs);  //bit_depth_luma_minus8
    read_golomb_ue(bs);  //bit_depth_chroma_minus8
    read_bits1(bs);

    if(read_bits1(bs)) {
      /* Scaling matrices */
      decode_scaling_list(bs, 16);
      decode_scaling_list(bs, 16);
      decode_scaling_list(bs, 16);
      decode_scaling_list(bs, 16);
      decode_scaling_list(bs, 16);
      decode_scaling_list(bs, 16);

      decode_scaling_list(bs, 64);
      decode_scaling_list(bs, 64);

    }
  }

  p->sps[sps_id].max_frame_num_bits = read_golomb_ue(bs) + 4;
  poc_type= read_golomb_ue(bs);
 
  if(poc_type == 0){ //FIXME #define
    read_golomb_ue(bs);
  } else if(poc_type == 1){//FIXME #define
    read_bits1(bs);
    read_golomb_se(bs);
    read_golomb_se(bs);
    tmp = read_golomb_ue(bs); /* poc_cycle_length */
    for(i = 0; i < tmp; i++)
      read_golomb_se(bs);

  }else if(poc_type != 2){
    /* Illegal poc */
    return -1;
  }

  tmp = read_golomb_ue(bs);

  read_bits1(bs);

  width = read_golomb_ue(bs) + 1; /* mb width */
  height = read_golomb_ue(bs) + 1; /* mb height */

  p->sps[sps_id].width = width * 16;
  p->sps[sps_id].height = height * 16;

  p->sps[sps_id].mbs_only_flag = read_bits1(bs);
  if(!p->sps[sps_id].mbs_only_flag)
    p->sps[sps_id].aff = read_bits1(bs);

  read_bits1(bs);

  /* CROP */
  if(read_bits1(bs)){
    tmp = read_golomb_ue(bs);
    tmp = read_golomb_ue(bs);
    tmp = read_golomb_ue(bs);
    tmp = read_golomb_ue(bs);
  }

  if(read_bits1(bs)) {
    decode_vui(p, bs, sps_id);
    return 0;
  } else {
    return -1;
  }
}
예제 #16
0
파일: exodecr.c 프로젝트: yellows8/dsi
char *
exo_decrunch(const char *in, char *out)
{
    unsigned short int index;
    unsigned short int length;
    unsigned short int offset;
    char c;
    char literal;

    bit_buffer = *--in;

    init_table(&in);
    for(;;)
    {
        literal = read_bits(&in, 1);
        if(literal == 1)
        {
            /* literal byte */
            length = 1;
            goto copy;
        }
        index = 0;
        while(read_bits(&in, 1) == 0)
        {
            ++index;
        }
        if(index == 16)
        {
            break;
        }
        if(index == 17)
        {
            literal = 1;
            length = read_bits(&in, 16);
            goto copy;
        }
        length = base[index] + read_bits(&in, bits[index]);
        switch(length)
        {
        case 1:
            index = 48 + read_bits(&in, 2);
            break;
        case 2:
            index = 32 + read_bits(&in, 4);
            break;
        default:
            index = 16 + read_bits(&in, 4);
            break;
        }
        offset = base[index] + read_bits(&in, bits[index]);
    copy:
        do
        {
            --out;
            if(literal)
            {
                c = *--in;
            }
            else
            {
                c = out[offset];
            }
            *out = c;
        }
        while(--length > 0);
    }
    return out;
}
예제 #17
0
// Return TRUE if the data parsing finished, FALSE otherwise.
// estream->pos is advanced. Data is only processed if esstream->error
// is FALSE, parsing can set esstream->error to TRUE.
static int sequence_header(struct lib_ccx_ctx *ctx, struct bitstream *esstream)
{
    dbg_print(CCX_DMT_VERBOSE, "Sequence header\n");

    if (esstream->error || esstream->bitsleft <= 0)
        return 0;

    // We only get here after seeing that start code
    if (read_u32(esstream) != 0xB3010000) // LSB first (0x000001B3)
        fatal(CCX_COMMON_EXIT_BUG_BUG, "Impossible!");

    unsigned hor_size = (unsigned) read_bits(esstream,12);
    unsigned vert_size = (unsigned) read_bits(esstream,12);
    unsigned aspect_ratio = (unsigned) read_bits(esstream,4);
    unsigned frame_rate = (unsigned) read_bits(esstream,4);

    ctx->freport.width = hor_size;
    ctx->freport.height = vert_size;
    ctx->freport.aspect_ratio = aspect_ratio;
    ctx->freport.frame_rate = frame_rate;

    // Discard some information
    read_bits(esstream, 18+1+10+1);

    // load_intra_quantiser_matrix
    if (read_bits(esstream,1))
        skip_bits(esstream, 8*64);
    // load_non_intra_quantiser_matrix
    if (read_bits(esstream,1))
        skip_bits(esstream, 8*64);

    if (esstream->bitsleft < 0)
        return 0;

    // If we got the whole sequence, process
    if (hor_size!=current_hor_size ||
        vert_size!=current_vert_size ||
        aspect_ratio!=current_aspect_ratio ||
        frame_rate!=current_frame_rate)
    {
        // If horizontal/vertical size, framerate and/or aspect
        // ratio are ilegal, we discard the
        // whole sequence info.
        if (vert_size >= 288 && vert_size <= 1088 &&
            hor_size >= 352 && hor_size <= 1920 &&
            hor_size / vert_size >= 352/576 && hor_size / vert_size <= 2 &&
            frame_rate>0 && frame_rate<9 &&
            aspect_ratio>0 && aspect_ratio<5)
        {
            mprint ("\n\nNew video information found");
            if (pts_set==2)
            {
                unsigned cur_sec = (unsigned) ((current_pts - min_pts)
                                               / MPEG_CLOCK_FREQ);
                mprint (" at %02u:%02u",cur_sec/60, cur_sec % 60);
            }
            mprint ("\n");
            mprint ("[%u * %u] [AR: %s] [FR: %s]",
                    hor_size,vert_size,
                    aspect_ratio_types[aspect_ratio],
                    framerates_types[frame_rate]);
            // No newline, force the output of progressive info in picture
            // info part.
            current_progressive_sequence = 2;

            current_hor_size=hor_size;
            current_vert_size=vert_size;
            current_aspect_ratio=aspect_ratio;
            current_frame_rate=frame_rate;
            current_fps = framerates_values[current_frame_rate];
            activity_video_info (hor_size,vert_size,
                                 aspect_ratio_types[aspect_ratio],
                                 framerates_types[frame_rate]);
        }
        else
        {
            dbg_print(CCX_DMT_VERBOSE, "\nInvalid sequence header:\n");
            dbg_print(CCX_DMT_VERBOSE, "V: %u H: %u FR: %u AS: %u\n",
                   vert_size, hor_size, frame_rate, aspect_ratio);
            esstream->error = 1;
            return 0;
        }
    }

    // Read complete
    return 1;
}
예제 #18
0
파일: imet1rsb.c 프로젝트: CWCorrea/RS
int main(int argc, char **argv) {

    FILE *fp;
    char *fpname;
    int i, len;

    int bitpos = 0,
        bit_ = 0,
        bit;
    char Bit = 0 /*,Bit0*/;
    float l = 0, l0 = 0, bitslen = 0;

#ifdef CYGWIN
    _setmode(fileno(stdin), _O_BINARY);  // _setmode(_fileno(stdin), _O_BINARY);
    setbuf(stdout, NULL);
#endif

    fpname = argv[0];
    ++argv;
    while ((*argv) && (!wavloaded)) {
        if      ( (strcmp(*argv, "-h") == 0) || (strcmp(*argv, "--help") == 0) ) {
            fprintf(stderr, "%s [options] audio.wav\n", fpname);
            fprintf(stderr, "  options:\n");
            fprintf(stderr, "       -r, --raw\n");
            return 0;
        }
/*
        else if ( (strcmp(*argv, "-v") == 0) || (strcmp(*argv, "--verbose") == 0) ) {
            option_verbose = 1;
        }
*/
        else if ( (strcmp(*argv, "-r") == 0) || (strcmp(*argv, "--raw") == 0) ) {
            option_raw = 1;
        }
        else if ( (strcmp(*argv, "-i") == 0) || (strcmp(*argv, "--invert") == 0) ) {
            option_inv = 1;
        }
        else {
            fp = fopen(*argv, "rb");
            if (fp == NULL) {
                fprintf(stderr, "%s konnte nicht geoeffnet werden\n", *argv);
                return -1;
            }
            wavloaded = 1;
        }
        ++argv;
    }
    if (!wavloaded) fp = stdin;


    i = read_wav_header(fp);
    if (i) {
        fclose(fp);
        return -1;
    }

    bitpos = 0;

    while (!read_bits(fp, &Bit, &l)) {

        if (l < 0.1) {
            bitslen = 0;
            continue;
        }

        if ((l0 < BIT01  &&  l < BIT01) || (l0 >= BIT01  &&  l >= BIT01)) {
            bitslen += l;
        }
        else {
            //fprintf(stderr, " %.1f\n", bitslen);
            if (Bit < 'a') bit = 0; else bit = 1;  // gesucht ist Bit zuvor
            len = (int)(bitslen+0.5);
            if (len < SYNC) {
            for (i = 0; i < len/2; i++) {
                //printf("%d", bit);
                if (bitpos < BAUD+10) {
                    bitframe[bitpos] = bit;
                }
                else { /* */ }
                bitpos++;
            }
            //printf(" %.1f=%d ", bitslen, len);
            }
            bitslen = l;
        }

        l0 = l;

        if (Bit < 'a') {
            bit_++;
        }
        else {
          if (bit_> SYNC) {
              if (bitpos < BAUD) print_frame((bitpos+7)/10);
              bitframe[0] = 1;
              bitpos = 1;
              //printf("\n1");
          }
          bit_ = 0;
        }

    }
    printf("\n");

    fclose(fp);

    return 0;
}
예제 #19
0
static void decode_channel(const uint8_t *base_addr, const channel_block &block, surface<float> *surf,
                           const std::vector<plane> &planes, const std::pair<float, float> range, bool negative_line_stride) {
    block_iterator it(block.w, block.h, surf);

    uint32_t n_blocks_in_line = (surf->width() / block.w);
    uint32_t n_block_lines = (surf->height() / block.h);

    // We need to support negative line stride.
    std::vector<std::pair<std::ptrdiff_t , std::ptrdiff_t >> line_offsets;
    for (const auto & plane : planes ) {
        if (negative_line_stride) {
            std::ptrdiff_t line_stride = -static_cast<std::ptrdiff_t>(plane.line_stride);
            // Each line  is still left to right.
            line_offsets.emplace_back(line_stride, plane.size + line_stride);
        } else {
            line_offsets.emplace_back(plane.line_stride, 0);
        }
    }

    // We need to preprocess the sample array to support continuation samples.
    std::vector<sample> samples;
    for (std::size_t i = 0; i < block.samples.size(); ) {
        const xyuv::sample &sample = block.samples[i];
        if (!sample.has_continuation) {
            samples.push_back(sample);
            i++;
        }
        else {
            // Create a descriptor block containing all the bits of the samples.
            xyuv::sample sample_descriptor;
            sample_descriptor.integer_bits = 0;
            sample_descriptor.fractional_bits = 0;
            sample_descriptor.has_continuation = true;
            samples.push_back(sample_descriptor);
            size_t descriptor_pos = samples.size() -1;
            do {
                // Update descriptor
                samples[descriptor_pos].integer_bits += block.samples[i].integer_bits;
                samples[descriptor_pos].fractional_bits += block.samples[i].fractional_bits;
                samples.push_back(block.samples[i]);
            } while(block.samples[i++].has_continuation);
        }
    }

    for (uint32_t line = 0; line < n_block_lines; line++) {
        for (uint32_t b = 0; b < n_blocks_in_line; b++) {
            for (std::size_t s = 0; s < samples.size(); ) {


                uint8_t integer_bits = samples[s].integer_bits;
                uint8_t fractional_bits = samples[s].fractional_bits;


                // If we hit a continuation block here, it means that we have the
                // Total bits descriptor and should skip it for the purpose of actual loading.
                if (samples[s].has_continuation) {
                    s++;
                }

                unorm_t unorm = 0;
                do {
                    const xyuv::sample &sample = samples[s];

                    const uint8_t * ptr_to_line =
                            // Start with offset to frame
                            base_addr +
                            // Add offset to lowest byte in plane.
                            planes[sample.plane].base_offset +
                            // Add the size of the plane if applicable.
                            line_offsets[sample.plane].second +
                            // Add offset to current line.
                            get_line(line, planes[sample.plane].interleave_mode, n_block_lines) * line_offsets[sample.plane].first;

                    // Read bits reads bits from MSb integer to LSb fractional bit.
                    read_bits( unorm,
                               ptr_to_line,
                               b * planes[sample.plane].block_stride + sample.offset,
                               sample.integer_bits + sample.fractional_bits);

                } while (samples[s++].has_continuation);

                float *value = it.advance();
                *value = from_unorm(unorm, integer_bits, fractional_bits, range);
            }
        }
    }
}
예제 #20
0
int
h264_decode_seq_parameter_set(elementary_stream_t *st, bitstream_t *bs)
{
  uint32_t profile_idc, level_idc, poc_type;
  uint32_t sps_id, tmp, i, width, height;
  uint32_t cbpsize, mbs_only_flag, aff;
  uint32_t max_frame_num_bits;
  uint32_t crop_left, crop_right, crop_top, crop_bottom;
  h264_private_t *p;
  h264_sps_t *sps;

  if ((p = st->es_priv) == NULL) {
    p = st->es_priv = calloc(1, sizeof(h264_private_t));
    p->start = dispatch_clock;
  }

  profile_idc = read_bits(bs, 8);
  skip_bits1(bs);   //constraint_set0_flag
  skip_bits1(bs);   //constraint_set1_flag
  skip_bits1(bs);   //constraint_set2_flag
  skip_bits1(bs);   //constraint_set3_flag
  skip_bits(bs, 4); // reserved
  level_idc = read_bits(bs, 8);

  sps_id = read_golomb_ue(bs);
  if(sps_id >= MAX_SPS_COUNT)
    return -1;
  sps = &p->sps[sps_id];

  i = 0;
  cbpsize = -1;
  while (h264_lev2cpbsize[i][0] != -1) {
    if (h264_lev2cpbsize[i][0] >= level_idc) {
      cbpsize = h264_lev2cpbsize[i][1];
      break;
    }
    i++;
  }
  if (cbpsize == -1)
    return -1;

  if (profile_idc >= 100){ //high profile
    tmp = read_golomb_ue(bs);
    if (tmp == 3)          //chroma_format_idc
      read_bits1(bs);      //residual_color_transform_flag
    read_golomb_ue(bs);    //bit_depth_luma_minus8
    read_golomb_ue(bs);    //bit_depth_chroma_minus8
    read_bits1(bs);        //transform_bypass

    if(read_bits1(bs)) {
      /* Scaling matrices */
      decode_scaling_list(bs, 16);
      decode_scaling_list(bs, 16);
      decode_scaling_list(bs, 16);
      decode_scaling_list(bs, 16);
      decode_scaling_list(bs, 16);
      decode_scaling_list(bs, 16);

      decode_scaling_list(bs, 64);
      decode_scaling_list(bs, 64);

    }
  }

  max_frame_num_bits = read_golomb_ue(bs) + 4;
  poc_type = read_golomb_ue(bs); // pic_order_cnt_type

  if(poc_type == 0){
    read_golomb_ue(bs);
  } else if(poc_type == 1){
    skip_bits1(bs);
    read_golomb_se(bs);
    read_golomb_se(bs);
    tmp = read_golomb_ue(bs); /* poc_cycle_length */
    for(i = 0; i < tmp; i++)
      read_golomb_se(bs);

  }else if(poc_type != 2){
    /* Illegal poc */
    return -1;
  }

  tmp = read_golomb_ue(bs);

  read_bits1(bs);

  width  = read_golomb_ue(bs) + 1; /* mb width */
  height = read_golomb_ue(bs) + 1; /* mb height */

  mbs_only_flag = read_bits1(bs);
  aff = 0;
  if(!mbs_only_flag)
    aff = read_bits1(bs);

  read_bits1(bs);

  /* CROP */
  crop_left = crop_right = crop_top = crop_bottom = 0;
  if (read_bits1(bs)){
    crop_left   = read_golomb_ue(bs) * 2;
    crop_right  = read_golomb_ue(bs) * 2;
    crop_top    = read_golomb_ue(bs) * 2;
    crop_bottom = read_golomb_ue(bs) * 2;
  }

  if (read_bits1(bs)) /* vui present */
    if (decode_vui(sps, bs))
      return -1;

  sps->max_frame_num_bits = max_frame_num_bits;
  sps->mbs_only_flag = mbs_only_flag;
  sps->aff = aff;
  sps->cbpsize = cbpsize * 125; /* Convert from kbit to bytes */
  sps->width   = width  * 16 - crop_left - crop_right;
  sps->height  = height * 16 - crop_top  - crop_bottom;
  sps->valid   = 1;

  return 0;
}
예제 #21
0
// Parse the user data for captions. The udtype variable denotes
// to which type of data it belongs:
// 0 .. sequence header
// 1 .. GOP header
// 2 .. picture header
// Return TRUE if the data parsing finished, FALSE otherwise.
// estream->pos is advanced. Data is only processed if ustream->error
// is FALSE, parsing can set ustream->error to TRUE.
int user_data(struct lib_cc_decode *ctx, struct bitstream *ustream, int udtype, struct cc_subtitle *sub)
{
	dbg_print(CCX_DMT_VERBOSE, "user_data(%d)\n", udtype);

	// Shall not happen
	if (ustream->error || ustream->bitsleft <= 0)
	{
		// ustream->error=1;
		return 0; // Actually discarded on call.
		// CFS: Seen in a Wobble edited file.
		// fatal(CCX_COMMON_EXIT_BUG_BUG, "user_data: Impossible!");
	}

	// Do something
	ctx->stat_numuserheaders++;
	//header+=4;

	unsigned char *ud_header = next_bytes(ustream, 4);
	if (ustream->error || ustream->bitsleft <= 0)
	{
		return 0;  // Actually discarded on call.
		// CFS: Seen in Stick_VHS.mpg.
		// fatal(CCX_COMMON_EXIT_BUG_BUG, "user_data: Impossible!");
	}

	// DVD CC header, see
	// <http://www.theneitherworld.com/mcpoodle/SCC_TOOLS/DOCS/SCC_FORMAT.HTML>
	if ( !memcmp(ud_header,"\x43\x43", 2 ) )
	{
		ctx->stat_dvdccheaders++;

		// Probably unneeded, but keep looking for extra caption blocks
		int maybeextracb = 1;

		read_bytes(ustream, 4); // "43 43 01 F8"

		unsigned char pattern_flag = (unsigned char) read_bits(ustream,1);
		read_bits(ustream,1);
		int capcount=(int) read_bits(ustream,5);
		int truncate_flag = (int) read_bits(ustream,1); // truncate_flag - one CB extra

		int field1packet = 0; // expect Field 1 first
		if (pattern_flag == 0x00)
			field1packet=1; // expect Field 1 second

		dbg_print(CCX_DMT_VERBOSE, "Reading %d%s DVD CC segments\n",
				capcount, (truncate_flag?"+1":""));

		capcount += truncate_flag;

		// This data comes before the first frame header, so
		// in order to get the correct timing we need to set the
		// current time to one frame after the maximum time of the
		// last GOP.  Only useful when there are frames before
		// the GOP.
		if (ctx->timing->fts_max > 0)
			ctx->timing->fts_now = ctx->timing->fts_max + (LLONG) (1000.0/current_fps);

		int rcbcount = 0;
		for (int i=0; i<capcount; i++)
		{
			for (int j=0;j<2;j++)
			{
				unsigned char data[3];
				data[0]=read_u8(ustream);
				data[1]=read_u8(ustream);
				data[2]=read_u8(ustream);

				// Obey the truncate flag.
				if ( truncate_flag && i == capcount-1 && j == 1 )
				{
					maybeextracb = 0;
					break;
				}
				/* Field 1 and 2 data can be in either order,
				   with marker bytes of \xff and \xfe
				   Since markers can be repeated, use pattern as well */
				if ((data[0]&0xFE) == 0xFE) // Check if valid
				{
					if (data[0]==0xff && j==field1packet)
						data[0]=0x04; // Field 1
					else
						data[0]=0x05; // Field 2
					do_cb(ctx, data, sub);
					rcbcount++;
				}
				else
				{
					dbg_print(CCX_DMT_VERBOSE, "Illegal caption segment - stop here.\n");
					maybeextracb = 0;
					break;
				}
			}
		}
		// Theoretically this should not happen, oh well ...
		// Deal with extra closed captions some DVD have.
		int ecbcount = 0;
		while ( maybeextracb && (next_u8(ustream)&0xFE) == 0xFE )
		{
			for (int j=0;j<2;j++)
			{
				unsigned char data[3];
				data[0]=read_u8(ustream);
				data[1]=read_u8(ustream);
				data[2]=read_u8(ustream);
				/* Field 1 and 2 data can be in either order,
				   with marker bytes of \xff and \xfe
				   Since markers can be repeated, use pattern as well */
				if ((data[0]&0xFE) == 0xFE) // Check if valid
				{
					if (data[0]==0xff && j==field1packet)
						data[0]=0x04; // Field 1
					else
						data[0]=0x05; // Field 2
					do_cb(ctx, data, sub);
					ecbcount++;
				}
				else
				{
					dbg_print(CCX_DMT_VERBOSE, "Illegal (extra) caption segment - stop here.\n");
					maybeextracb = 0;
					break;
				}
			}
		}

		dbg_print(CCX_DMT_VERBOSE, "Read %d/%d DVD CC blocks\n", rcbcount, ecbcount);
	}
	// SCTE 20 user data
	else if (!ctx->noscte20 && ud_header[0] == 0x03)
	{
		if ((ud_header[1]&0x7F) == 0x01)
		{
			unsigned char cc_data[3*31+1]; // Maximum cc_count is 31

			ctx->stat_scte20ccheaders++;
			read_bytes(ustream, 2); // "03 01"

			unsigned cc_count = (unsigned int) read_bits(ustream,5);
			dbg_print(CCX_DMT_VERBOSE, "Reading %d SCTE 20 CC blocks\n", cc_count);

			unsigned field_number;
			unsigned cc_data1;
			unsigned cc_data2;

			for (unsigned j=0;j<cc_count;j++)
			{
				skip_bits(ustream,2); // priority - unused
				field_number = (unsigned int) read_bits(ustream,2);
				skip_bits(ustream,5); // line_offset - unused
				cc_data1 = (unsigned int) read_bits(ustream,8);
				cc_data2 = (unsigned int) read_bits(ustream,8);
				read_bits(ustream,1); // TODO: Add syntax check */

				if (ustream->bitsleft < 0)
					fatal(CCX_COMMON_EXIT_BUG_BUG, "In user_data: ustream->bitsleft < 0. Cannot continue.");

				// Field_number is either
				//  0 .. forbidden
				//  1 .. field 1 (odd)
				//  2 .. field 2 (even)
				//  3 .. repeated, from repeat_first_field, effectively field 1
				if (field_number < 1)
				{
					// 0 is invalid
					cc_data[j*3]=0x00; // Set to invalid
					cc_data[j*3+1]=0x00;
					cc_data[j*3+2]=0x00;
				}
				else
				{
					// Treat field_number 3 as 1
					field_number = (field_number - 1) & 0x01;
					// top_field_first also affects to which field the caption
					// belongs.
					if(!ctx->top_field_first)
						field_number ^= 0x01;
					cc_data[j*3]=0x04|(field_number);
					cc_data[j*3+1]=reverse8(cc_data1);
					cc_data[j*3+2]=reverse8(cc_data2);
				}
			}
			cc_data[cc_count*3]=0xFF;
			store_hdcc(ctx, cc_data, cc_count, ctx->timing->current_tref, ctx->timing->fts_now, sub);

			dbg_print(CCX_DMT_VERBOSE, "Reading SCTE 20 CC blocks - done\n");
		}
		// reserved - unspecified
	}
	// ReplayTV 4000/5000 caption header - parsing information
	// derived from CCExtract.bdl
	else if ( (ud_header[0] == 0xbb     //ReplayTV 4000
				|| ud_header[0] == 0x99) //ReplayTV 5000
			&& ud_header[1] == 0x02 )
	{
		unsigned char data[3];

		if (ud_header[0]==0xbb)
			ctx->stat_replay4000headers++;
		else
			ctx->stat_replay5000headers++;


		read_bytes(ustream, 2); // "BB 02" or "99 02"
		data[0]=0x05; // Field 2
		data[1]=read_u8(ustream);
		data[2]=read_u8(ustream);
		do_cb(ctx, data, sub);
		read_bytes(ustream, 2); // Skip "CC 02" for R4000 or "AA 02" for R5000
		data[0]=0x04; // Field 1
		data[1]=read_u8(ustream);
		data[2]=read_u8(ustream);
		do_cb(ctx, data, sub);
	}
	// HDTV - see A/53 Part 4 (Video)
	else if ( !memcmp(ud_header,"\x47\x41\x39\x34", 4 ) )
	{
		ctx->stat_hdtv++;

		read_bytes(ustream, 4); // "47 41 39 34"

		unsigned char type_code = read_u8(ustream);
		if (type_code==0x03) // CC data.
		{
			skip_bits(ustream,1); // reserved
			unsigned char process_cc_data = (unsigned char) read_bits(ustream,1);
			skip_bits(ustream,1); // additional_data - unused
			unsigned char cc_count = (unsigned char) read_bits(ustream,5);
			read_bytes(ustream, 1); // "FF"
			if (process_cc_data)
			{
				dbg_print(CCX_DMT_VERBOSE, "Reading %d HDTV CC blocks\n", cc_count);

				int proceed = 1;
				unsigned char *cc_data = read_bytes(ustream, cc_count*3);
				if (ustream->bitsleft < 0)
					fatal(CCX_COMMON_EXIT_BUG_BUG, "In user_data: ustream->bitsleft < 0. Cannot continue.\n");

				// Check for proper marker - This read makes sure that
				// cc_count*3+1 bytes are read and available in cc_data.
				if (read_u8(ustream)!=0xFF)
					proceed=0;

				if (!proceed)
				{
					dbg_print(CCX_DMT_VERBOSE, "\rThe following payload is not properly terminated.\n");
					dump (CCX_DMT_VERBOSE, cc_data, cc_count*3+1, 0, 0);
				}
				dbg_print(CCX_DMT_VERBOSE, "Reading %d HD CC blocks\n", cc_count);

				// B-frames might be (temporal) before or after the anchor
				// frame they belong to. Store the buffer until the next anchor
				// frame occurs.  The buffer will be flushed (sorted) in the
				// picture header (or GOP) section when the next anchor occurs.
				// Please note we store the current value of the global
				// fts_now variable (and not get_fts()) as we are going to
				// re-create the timeline in process_hdcc() (Slightly ugly).
				store_hdcc(ctx, cc_data, cc_count, ctx->timing->current_tref, ctx->timing->fts_now, sub);

				dbg_print(CCX_DMT_VERBOSE, "Reading HDTV blocks - done\n");
			}
		}
		// reserved - additional_cc_data
	}
	// DVB closed caption header for Dish Network (Field 1 only) */
	else if ( !memcmp(ud_header,"\x05\x02", 2 ) )
	{
		// Like HDTV (above) Dish Network captions can be stored at each
		// frame, but maximal two caption blocks per frame and only one
		// field is stored.
		// To process this with the HDTV framework we create a "HDTV" caption
		// format compatible array. Two times 3 bytes plus one for the 0xFF
		// marker at the end. Pre-init to field 1 and set the 0xFF marker.
		static unsigned char dishdata[7] = {0x04, 0, 0, 0x04, 0, 0, 0xFF};
		int cc_count;

		dbg_print(CCX_DMT_VERBOSE, "Reading Dish Network user data\n");

		ctx->stat_dishheaders++;

		read_bytes(ustream, 2); // "05 02"

		// The next bytes are like this:
		// header[2] : ID: 0x04 (MPEG?), 0x03 (H264?)
		// header[3-4]: Two byte counter (counting (sub-)GOPs?)
		// header[5-6]: Two bytes, maybe checksum?
		// header[7]: Pattern type
		//            on B-frame: 0x02, 0x04
		//            on I-/P-frame: 0x05
		unsigned char id = read_u8(ustream);
		unsigned dishcount = read_u16(ustream);
		unsigned something = read_u16(ustream);
		unsigned char type = read_u8(ustream);
		dbg_print(CCX_DMT_PARSE, "DN  ID: %02X  Count: %5u  Unknown: %04X  Pattern: %X",
				id, dishcount, something, type);

		unsigned char hi;

		// The following block needs 4 to 6 bytes starting from the
		// current position
		unsigned char *dcd = ustream->pos; // dish caption data
		switch (type)
		{
			case 0x02:
				// Two byte caption - always on B-frame
				// The following 4 bytes are:
				// 0  :  0x09
				// 1-2: caption block
				// 3  : REPEAT - 02: two bytes
				//             - 04: four bytes (repeat first two)
				dbg_print(CCX_DMT_PARSE, "\n02 %02X  %02X:%02X - R:%02X :",
						dcd[0], dcd[1], dcd[2], dcd[3]);

				cc_count = 1;
				dishdata[1]=dcd[1];
				dishdata[2]=dcd[2];

				dbg_print(CCX_DMT_PARSE, "%s", debug_608_to_ASC( dishdata, 0) );

				type=dcd[3];  // repeater (0x02 or 0x04)
				hi = dishdata[1] & 0x7f; // Get only the 7 low bits
				if (type==0x04 && hi<32) // repeat (only for non-character pairs)
				{
					cc_count = 2;
					dishdata[3]=0x04; // Field 1
					dishdata[4]=dishdata[1];
					dishdata[5]=dishdata[2];

					dbg_print(CCX_DMT_PARSE, "%s:\n", debug_608_to_ASC( dishdata+3, 0) );
				}
				else
				{
					dbg_print(CCX_DMT_PARSE, ":\n");
				}

				dishdata[cc_count*3] = 0xFF; // Set end marker

				store_hdcc(ctx, dishdata, cc_count, ctx->timing->current_tref, ctx->timing->fts_now, sub);

				// Ignore 3 (0x0A, followed by two unknown) bytes.
				break;
			case 0x04:
				// Four byte caption - always on B-frame
				// The following 5 bytes are:
				// 0  :  0x09
				// 1-2: caption block
				// 3-4: caption block
				dbg_print(CCX_DMT_PARSE, "\n04 %02X  %02X:%02X:%02X:%02X  :",
						dcd[0], dcd[1], dcd[2], dcd[3], dcd[4]);

				cc_count = 2;
				dishdata[1]=dcd[1];
				dishdata[2]=dcd[2];

				dishdata[3]=0x04; // Field 1
				dishdata[4]=dcd[3];
				dishdata[5]=dcd[4];
				dishdata[6] = 0xFF; // Set end marker

				dbg_print(CCX_DMT_PARSE, "%s", debug_608_to_ASC( dishdata, 0) );
				dbg_print(CCX_DMT_PARSE, "%s:\n", debug_608_to_ASC( dishdata+3, 0) );

				store_hdcc(ctx, dishdata, cc_count, ctx->timing->current_tref, ctx->timing->fts_now, sub);

				// Ignore 4 (0x020A, followed by two unknown) bytes.
				break;
			case 0x05:
				// Buffered caption - always on I-/P-frame
				// The following six bytes are:
				// 0  :  0x04
				// - the following are from previous 0x05 caption header -
				// 1  : prev dcd[2]
				// 2-3: prev dcd[3-4]
				// 4-5: prev dcd[5-6]
				dbg_print(CCX_DMT_PARSE, " - %02X  pch: %02X %5u %02X:%02X\n",
						dcd[0], dcd[1],
						(unsigned)dcd[2]*256+dcd[3],
						dcd[4], dcd[5]);
				dcd+=6; // Skip these 6 bytes

				// Now one of the "regular" 0x02 or 0x04 captions follows
				dbg_print(CCX_DMT_PARSE, "%02X %02X  %02X:%02X",
						dcd[0], dcd[1], dcd[2], dcd[3]);

				type=dcd[0]; // Number of caption bytes (0x02 or 0x04)

				cc_count = 1;
				dishdata[1]=dcd[2];
				dishdata[2]=dcd[3];

				dcd+=4; // Skip the first 4 bytes.
				if (type==0x02)
				{
					type=dcd[0]; // repeater (0x02 or 0x04)
					dcd++; // Skip the repeater byte.

					dbg_print(CCX_DMT_PARSE, " - R:%02X :%s", type, debug_608_to_ASC( dishdata, 0) );

					hi = dishdata[1] & 0x7f; // Get only the 7 low bits
					if (type==0x04 && hi<32)
					{
						cc_count = 2;
						dishdata[3]=0x04; // Field 1
						dishdata[4]=dishdata[1];
						dishdata[5]=dishdata[2];
						dbg_print(CCX_DMT_PARSE, "%s:\n", debug_608_to_ASC( dishdata+3, 0) );
					}
					else
					{
						dbg_print(CCX_DMT_PARSE, ":\n");
					}
					dishdata[cc_count*3] = 0xFF; // Set end marker
				}
				else
				{
					dbg_print(CCX_DMT_PARSE, ":%02X:%02X  ",
							dcd[0], dcd[1]);
					cc_count = 2;
					dishdata[3]=0x04; // Field 1
					dishdata[4]=dcd[0];
					dishdata[5]=dcd[1];
					dishdata[6] = 0xFF; // Set end marker

					dbg_print(CCX_DMT_PARSE, ":%s", debug_608_to_ASC( dishdata, 0) );
					dbg_print(CCX_DMT_PARSE, "%s:\n", debug_608_to_ASC( dishdata+3, 0) );
				}

				store_hdcc(ctx, dishdata, cc_count, ctx->timing->current_tref, ctx->timing->fts_now, sub);

				// Ignore 3 (0x0A, followed by 2 unknown) bytes.
				break;
			default:
				// printf ("Unknown?\n");
				break;
		} // switch

		dbg_print(CCX_DMT_VERBOSE, "Reading Dish Network user data - done\n");
	}
	// CEA 608 / aka "Divicom standard", see:
	// http://www.pixeltools.com/tech_tip_closed_captioning.html
	else if ( !memcmp(ud_header,"\x02\x09", 2 ) )
	{
		// Either a documentation or more examples are needed.
		ctx->stat_divicom++;

		unsigned char data[3];

		read_bytes(ustream, 2); // "02 09"
		read_bytes(ustream, 2); // "80 80" ???
		read_bytes(ustream, 2); // "02 0A" ???
		data[0]=0x04; // Field 1
		data[1]=read_u8(ustream);
		data[2]=read_u8(ustream);
		do_cb(ctx, data, sub);
		// This is probably incomplete!
	}
	// GXF vbi OEM code
	else if ( !memcmp(ud_header,"\x73\x52\x21\x06", 4 ) )
	{
		int udatalen = ustream->end - ustream->pos;
		uint16_t line_nb;
		uint8_t line_type;
		uint8_t field = 1;
		read_bytes(ustream, 4); //skip header code
		read_bytes(ustream, 2); //skip data length
		line_nb = read_bits(ustream, 16);
		line_type = read_u8(ustream);
		field = (line_type & 0x03);
		if(field == 0)
			mprint("MPEG:VBI: Invalid field\n");

		line_type = line_type >> 2;
		if(line_type != 1)
			mprint("MPEG:VBI: only support Luma line\n");

		if (udatalen < 720)
			mprint("MPEG:VBI: Minimum 720 bytes in luma line required\n");

		decode_vbi(ctx, field, ustream->pos, 720, sub);
		dbg_print(CCX_DMT_VERBOSE, "GXF (vbi line %d) user data:\n", line_nb);
	}
예제 #22
0
unsigned int
read_bits1(bitstream_t *bs)
{
  return read_bits(bs, 1);
}
예제 #23
0
파일: ps.c 프로젝트: seanvk/MiniVideo
/*!
 * \brief Parse a mp4 file.
 * \param *video A pointer to a VideoFile_t structure.
 * \return retcode 1 if succeed, 0 otherwise.
 *
 * This parser is based on the 'ISO/IEC 13818-1' international standard, part 1:
 * 'Transmission multiplexing and synchronization'.
 */
int ps_fileParse(VideoFile_t *video)
{
    TRACE_INFO(MPS, BLD_GREEN "ps_fileParse()\n" CLR_RESET);
    int retcode = SUCCESS;
    int sid = 0;

    // Init bitstream to parse container infos
    Bitstream_t *bitstr = init_bitstream(video, NULL);

    if (bitstr != NULL)
    {
        // Init bitstream_map to store container infos
        retcode = init_bitstream_map(&video->tracks_audio[0], 999999);
        retcode = init_bitstream_map(&video->tracks_video[0], 999999);

        if (retcode == SUCCESS)
        {
            video->tracks_audio[0]->stream_type = stream_AUDIO;
            video->tracks_audio[0]->stream_level = stream_level_PES;
            video->tracks_audio[0]->stream_codec = CODEC_MPEG_L3;
            video->tracks_audio[0]->sample_alignment = false;

            video->tracks_video[0]->stream_type = stream_VIDEO;
            video->tracks_video[0]->stream_level = stream_level_PES;
            video->tracks_video[0]->stream_codec = CODEC_MPEG12;
            video->tracks_video[0]->sample_alignment = false;

            // Read bitstream
            while (retcode == SUCCESS &&
                   (bitstream_get_absolute_byte_offset(bitstr) + 4) < video->file_size &&
                   next_bits(bitstr, 32) != PES_PROGRAM_END)
            {
                PackHeader_t pack_header;
                SystemHeader_t system_header;

                if (read_bits(bitstr, 32) == PES_PACK_HEADER)
                {
                    // Parse pack & system header
                    retcode = parse_pack_header(bitstr, &pack_header, &system_header);

                    // Then loop on PES
                    while (retcode == SUCCESS &&
                           (bitstream_get_absolute_byte_offset(bitstr) + 4) < video->file_size &&
                           next_bits(bitstr, 32) != PES_PACK_HEADER &&
                           next_bits(bitstr, 32) != PES_PROGRAM_END)
                    {
                        // Init
                        PesPacket_t pes_packet;
                        ProgramStreamMap_t pes_streammap;
                        ProgramStreamDirectory_t pes_streamdirectory;

                        // Parse start code
                        pes_packet.packet_start_offset = bitstream_get_absolute_byte_offset(bitstr);
                        pes_packet.packet_start_code   = read_bits(bitstr, 24);
                        pes_packet.stream_id           = (uint8_t)read_bits(bitstr, 8);

                        if (pes_packet.packet_start_code == PES_PACKETSTARTCODE)
                        {
                            switch (pes_packet.stream_id)
                            {
                            case SID_PROGRAM_STREAM_MAP:
                                retcode = parse_program_stream_map(bitstr, &pes_streammap);
                                break;
                            case SID_PROGRAM_STREAM_DIRECTORY:
                                retcode = parse_program_stream_directory(bitstr, &pes_streamdirectory);
                                break;
                            case SID_PADDING:
                                retcode = parse_pes_padding(bitstr, &pes_packet);
                                break;
                            case SID_PRIVATE_STREAM_1:
                                TRACE_2(MPS, BLD_GREEN "Private Stream 1 PES" CLR_RESET " @ %i\n", pes_packet.packet_start_offset);
                                retcode = skip_pes(bitstr, &pes_packet);
                                break;
                            case SID_PRIVATE_STREAM_2:
                                TRACE_2(MPS, BLD_GREEN "Private Stream 2 PES" CLR_RESET " @ %i\n", pes_packet.packet_start_offset);
                                retcode = skip_pes(bitstr, &pes_packet);
                                break;
                            case SID_VIDEO:
                                TRACE_INFO(MPS, BLD_GREEN "parse_pes_video()" CLR_RESET " @ %i\n", pes_packet.packet_start_offset);
                                retcode = parse_pes(bitstr, &pes_packet);
                                //print_pes(&pes_packet);

                                // Set sample into the bitstream_map
                                video->tracks_video[0]->sample_count++;
                                sid = video->tracks_video[0]->sample_count;
                                if (sid < 999999)
                                {
                                    video->tracks_video[0]->sample_type[sid] = sample_VIDEO;
                                    video->tracks_video[0]->sample_size[sid] = pes_packet.PES_packet_length + 6;
                                    video->tracks_video[0]->sample_offset[sid] = pes_packet.packet_start_offset;
                                    video->tracks_video[0]->sample_pts[sid] = pes_packet.PTS;
                                    video->tracks_video[0]->sample_dts[sid] = pes_packet.DTS;
                                }
                                break;
                            case SID_AUDIO:
                                TRACE_INFO(MPS, BLD_GREEN "parse_pes_audio()" CLR_RESET " @ %i\n", pes_packet.packet_start_offset);
                                retcode = parse_pes(bitstr, &pes_packet);
                                //print_pes(&pes_packet);

                                // Set sample into the bitstream_map
                                video->tracks_audio[0]->sample_count++;
                                sid = video->tracks_audio[0]->sample_count;
                                if (sid < 999999)
                                {
                                    video->tracks_audio[0]->sample_type[sid] = sample_AUDIO;
                                    video->tracks_audio[0]->sample_size[sid] = pes_packet.PES_packet_length + 6;
                                    video->tracks_audio[0]->sample_offset[sid] = pes_packet.packet_start_offset;
                                    video->tracks_audio[0]->sample_pts[sid] = pes_packet.PTS;
                                    video->tracks_audio[0]->sample_dts[sid] = pes_packet.DTS;
                                }
                                break;
                            default:
                                TRACE_WARNING(MPS, "Unknown PES type (0x%06X%02X) @ %i\n", pes_packet.packet_start_code, pes_packet.stream_id, pes_packet.packet_start_offset);
                                retcode = skip_pes(bitstr, &pes_packet);
                                break;
                            }
                        }
                        else
                        {
                            TRACE_ERROR(MPS, "No valid packet_start_code at %i\n", pes_packet.packet_start_offset);
                            retcode = FAILURE;
                        }
                    }
                }
                else
                {
                    TRACE_ERROR(MPS, "No pack header\n");
                    retcode = FAILURE;
                }
            }
        }

        // Free bitstream
        free_bitstream(&bitstr);
    }

    return retcode;
}
예제 #24
0
파일: ps.cpp 프로젝트: emericg/MiniVideo
/*!
 * \brief Parse a system header structure.
 * \param *bitstr The bitstream to use.
 * \param *system_header A pointer to a system_header structure.
 * \return 1 if succeed, 0 otherwise.
 *
 * From 'ISO/IEC 13818-1' specification:
 * 2.5.3.5 System header.
 * Table 2-34 – Program Stream system header
 */
static int parse_system_header(Bitstream_t *bitstr, PesHeader_t *header, SystemHeader_t *packet)
{
    int retcode = SUCCESS;

    TRACE_INFO(MPS, BLD_GREEN "parse_system_header()" CLR_RESET " @ %lli",
               header->offset_start);

    MARKER_BIT
    packet->rate_bound = read_bits(bitstr, 22);
    MARKER_BIT
    packet->audio_bound = read_bits(bitstr, 6);
    packet->fixed_flag = read_bits(bitstr, 1);
    packet->CSPS_flag = read_bits(bitstr, 1);
    packet->system_audio_lock_flag = read_bits(bitstr, 1);
    packet->system_video_lock_flag = read_bits(bitstr, 1);
    MARKER_BIT
    packet->video_bound = read_bits(bitstr, 5);
    packet->packet_rate_restriction_flag = read_bits(bitstr, 1);

    /*unsigned reserved_bits =*/ read_bits(bitstr, 7);

    // stack it?
    while (next_bit(bitstr) == 1)
    {
        packet->stream_id = read_bits(bitstr, 8);
        MARKER_BIT
        MARKER_BIT
        packet->PSTD_buffer_bound_scale = read_bits(bitstr, 1);
        packet->PSTD_buffer_size_bound = read_bits(bitstr, 13);
    }

    return retcode;
}
예제 #25
0
/*!
 * \brief Read prediction informations for current macroblock.
 * \param *dc The current DecodingContext.
 * \param *mb The current macroblock.
 *
 * Intra prediction infos are a table containing prediction mode for each blocks.
 * Inter prediction infos are motion vectors.
 */
static void mb_pred(DecodingContext_t *dc, Macroblock_t *mb)
{
    TRACE_INFO(MB, "  > " BLD_GREEN "mb_pred()\n" CLR_RESET);

    if (mb->MbPartPredMode[0] == Intra_4x4 ||
        mb->MbPartPredMode[0] == Intra_8x8 ||
        mb->MbPartPredMode[0] == Intra_16x16)
    {
        if (mb->MbPartPredMode[0] == Intra_4x4)
        {
            // Read intra prediction mode for all 16 4x4 luma blocks
            unsigned int luma4x4BlkIdx = 0;
            for (luma4x4BlkIdx = 0; luma4x4BlkIdx < 16; luma4x4BlkIdx++)
            {
                if (dc->entropy_coding_mode_flag)
                    mb->prev_intra4x4_pred_mode_flag[luma4x4BlkIdx] = read_ae(dc, SE_prev_intraxxx_pred_mode_flag);
                else
                    mb->prev_intra4x4_pred_mode_flag[luma4x4BlkIdx] = read_bit(dc->bitstr);

                if (mb->prev_intra4x4_pred_mode_flag[luma4x4BlkIdx] == false)
                {
                    if (dc->entropy_coding_mode_flag)
                        mb->rem_intra4x4_pred_mode[luma4x4BlkIdx] = read_ae(dc, SE_rem_intraxxx_pred_mode);
                    else
                        mb->rem_intra4x4_pred_mode[luma4x4BlkIdx] = read_bits(dc->bitstr, 3);
                }
            }
        }
        else if (mb->MbPartPredMode[0] == Intra_8x8)
        {
            // Read intra prediction mode for all 4 8x8 luma blocks
            unsigned int luma8x8BlkIdx = 0;
            for (luma8x8BlkIdx = 0; luma8x8BlkIdx < 4; luma8x8BlkIdx++)
            {
                if (dc->entropy_coding_mode_flag)
                    mb->prev_intra8x8_pred_mode_flag[luma8x8BlkIdx] = read_ae(dc, SE_prev_intraxxx_pred_mode_flag);
                else
                    mb->prev_intra8x8_pred_mode_flag[luma8x8BlkIdx] = read_bit(dc->bitstr);

                if (mb->prev_intra8x8_pred_mode_flag[luma8x8BlkIdx] == false)
                {
                    if (dc->entropy_coding_mode_flag)
                        mb->rem_intra8x8_pred_mode[luma8x8BlkIdx] = read_ae(dc, SE_rem_intraxxx_pred_mode);
                    else
                        mb->rem_intra8x8_pred_mode[luma8x8BlkIdx] = read_bits(dc->bitstr, 3);
                }
            }
        }

        // Read intra prediction mode for chroma blocks
        if (dc->ChromaArrayType == 1 || dc->ChromaArrayType == 2)
        {
            if (dc->entropy_coding_mode_flag)
                mb->IntraChromaPredMode = read_ae(dc, SE_intra_chroma_pred_mode);
            else
                mb->IntraChromaPredMode = read_ue(dc->bitstr);
        }
    }
    else if (mb->MbPartPredMode[0] != Direct)
    {
        // ref_idx_l0
        unsigned int mbPartIdx = 0;
        for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++)
        {
            if ((dc->active_slice->num_ref_idx_l0_active_minus1 > 0 ||
                 dc->active_slice->mb_field_decoding_flag != dc->active_slice->field_pic_flag) &&
                MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L1)
            {
                if (dc->entropy_coding_mode_flag)
                    mb->ref_idx_l0[mbPartIdx] = read_ae(dc, SE_ref_idx_lx);
                else
                    mb->ref_idx_l0[mbPartIdx] = read_te(dc->bitstr, 0);
            }
        }

        // ref_idx_l1
        for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++)
        {
            if ((dc->active_slice->num_ref_idx_l1_active_minus1 > 0 ||
                 dc->active_slice->mb_field_decoding_flag != dc->active_slice->field_pic_flag) &&
                MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L0)
            {
                if (dc->entropy_coding_mode_flag)
                    mb->ref_idx_l1[mbPartIdx] = read_ae(dc, SE_ref_idx_lx);
                else
                    mb->ref_idx_l1[mbPartIdx] = read_te(dc->bitstr, 0);
            }
        }

        // mvd_l0
        for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++)
        {
            if (MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L1)
            {
                if (dc->entropy_coding_mode_flag)
                {
                    mb->mvd_l0[mbPartIdx][0][0] = read_ae(dc, SE_mvd_lx0);
                    mb->mvd_l0[mbPartIdx][0][1] = read_ae(dc, SE_mvd_lx1);
                }
                else
                {
                    mb->mvd_l0[mbPartIdx][0][0] = read_te(dc->bitstr, 0);
                    mb->mvd_l0[mbPartIdx][0][1] = read_te(dc->bitstr, 0);
                }
            }
        }

        // mvd_l1
        for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++)
        {
            if (MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L0)
            {
                if (dc->entropy_coding_mode_flag)
                {
                    mb->mvd_l1[mbPartIdx][0][0] = read_ae(dc, SE_mvd_lx0);
                    mb->mvd_l1[mbPartIdx][0][1] = read_ae(dc, SE_mvd_lx1);
                }
                else
                {
                    mb->mvd_l1[mbPartIdx][0][0] = read_te(dc->bitstr, 0);
                    mb->mvd_l1[mbPartIdx][0][1] = read_te(dc->bitstr, 0);
                }
            }
        }
    }
}
예제 #26
0
파일: ps.cpp 프로젝트: emericg/MiniVideo
/*!
 * \brief Parse a program stream directory structure.
 * \param *bitstr The bitstream to use.
 * \param *packet A program stream directory structure.
 * \return 1 if succeed, 0 otherwise.
 *
 * From 'ISO/IEC 13818-1' specification:
 * 2.5.5 Program Stream directory
 * Table 2-36 – Program Stream directory packet
 */
static int parse_program_stream_directory(Bitstream_t *bitstr, PesHeader_t *header, ProgramStreamDirectory_t *packet)
{
    TRACE_INFO(MPS, BLD_GREEN "parse_program_stream_directory()" CLR_RESET " @ %lli",
               header->offset_start);
    int retcode = SUCCESS;

    packet->number_of_access_units = read_bits(bitstr, 15);
    MARKER_BIT

    packet->prev_directory_offset = read_bits(bitstr, 15) << 30;
    MARKER_BIT
    packet->prev_directory_offset += read_bits(bitstr, 15) << 15;
    MARKER_BIT
    packet->prev_directory_offset += read_bits(bitstr, 15);
    MARKER_BIT

    packet->next_directory_offset = read_bits(bitstr, 15) << 30;
    MARKER_BIT
    packet->next_directory_offset += read_bits(bitstr, 15) << 15;
    MARKER_BIT
    packet->next_directory_offset += read_bits(bitstr, 15);
    MARKER_BIT

    for (uint16_t i = 0; i < packet->number_of_access_units; i++)
    {
        // TODO stack it?
        packet->packet_stream_id = read_bits(bitstr, 8);
        packet->PES_header_position_offset_sign = read_bit(bitstr);

        packet->PES_header_position_offset = read_bits(bitstr, 14) << 30;
        MARKER_BIT
        packet->PES_header_position_offset += read_bits(bitstr, 15) << 15;
        MARKER_BIT
        packet->PES_header_position_offset += read_bits(bitstr, 15);
        MARKER_BIT

        packet->reference_offset = read_bits(bitstr, 16);
        MARKER_BIT
        /*unsigned reserved1 =*/ read_bits(bitstr, 3);

        packet->PTS = read_bits(bitstr, 3) << 30;
        MARKER_BIT
        packet->PTS += read_bits(bitstr, 15) << 15;
        MARKER_BIT
        packet->PTS += read_bits(bitstr, 15);
        MARKER_BIT

        packet->byes_to_read = read_bits(bitstr, 15) << 15;
        MARKER_BIT
        packet->byes_to_read += read_bits(bitstr, 8);
        MARKER_BIT

        packet->intra_coded_indicator = read_bit(bitstr);
        packet->coding_parameters_indicator = read_bits(bitstr, 2);
        /*unsigned reserved2 =*/ read_bits(bitstr, 4);
    }

    return retcode;
}
예제 #27
0
int main(void) {
  uint16_t ontime, offtime;
  uint8_t i,j, Loop;
  uint8_t region = US;     // by default our code is US
  
  Loop = 0;                // by default we are not going to loop

  TCCR1 = 0;		   // Turn off PWM/freq gen, should be off already
  TCCR0A = 0;
  TCCR0B = 0;

  i = MCUSR;                     // Save reset reason
  MCUSR = 0;                     // clear watchdog flag
  WDTCR = _BV(WDCE) | _BV(WDE);  // enable WDT disable

  WDTCR = 0;                     // disable WDT while we setup

  DDRB = _BV(LED) | _BV(IRLED);   // set the visible and IR LED pins to outputs
  PORTB = _BV(LED) |              //  visible LED is off when pin is high
          _BV(IRLED) |            // IR LED is off when pin is high
          _BV(REGIONSWITCH);     // Turn on pullup on region switch pin

  // check the reset flags
  if (i & _BV(BORF)) {    // Brownout
    // Flash out an error and go to sleep
    flashslowLEDx(2);	
    tvbgone_sleep();  
  }

  delay_ten_us(5000);            // Let everything settle for a bit

  // determine region
  if (PINB & _BV(REGIONSWITCH)) {
    region = US; // US
  } else {
    region = EU;
  }

  // Tell the user what region we're in  - 3 is US 4 is EU
  quickflashLEDx(3+region);
  
  // Starting execution loop
  delay_ten_us(25000);
  
  // turn on watchdog timer immediately, this protects against
  // a 'stuck' system by resetting it
  wdt_enable(WDTO_8S); // 1 second long timeout

  do {	//Execute the code at least once.  If Loop is on, execute forever.

    // We may have different number of codes in either database
    if (region == US) {
      j = num_NAcodes;
    } else {
      j = num_EUcodes;
    }

    // for every POWER code in our collection
    for(i=0 ; i < j; i++) {   
      //To keep Watchdog from resetting in middle of code.
      wdt_reset();

      // point to next POWER code, from the right database
      if (region == US) {
	code_ptr = (PGM_P)pgm_read_word(NApowerCodes+i);  
      } else {
	code_ptr = (PGM_P)pgm_read_word(EUpowerCodes+i);  
      }

      // Read the carrier frequency from the first byte of code structure
      const uint8_t freq = pgm_read_byte(code_ptr++);
      // set OCR for Timer1 to output this POWER code's carrier frequency
      OCR0A = freq; 
      
      // Get the number of pairs, the second byte from the code struct
      const uint8_t numpairs = pgm_read_byte(code_ptr++);

      // Get the number of bits we use to index into the timer table
      // This is the third byte of the structure
      const uint8_t bitcompression = pgm_read_byte(code_ptr++);

      // Get pointer (address in memory) to pulse-times table
      // The address is 16-bits (2 byte, 1 word)
      const PGM_P time_ptr = (PGM_P)pgm_read_word(code_ptr);
      code_ptr+=2;

      // Transmit all codeElements for this POWER code 
      // (a codeElement is an onTime and an offTime)
      // transmitting onTime means pulsing the IR emitters at the carrier 
      // frequency for the length of time specified in onTime
      // transmitting offTime means no output from the IR emitters for the 
      // length of time specified in offTime

      // For EACH pair in this code....
      for (uint8_t k=0; k<numpairs; k++) {
	uint8_t ti;
	
	// Read the next 'n' bits as indicated by the compression variable
	// The multiply by 4 because there are 2 timing numbers per pair
	// and each timing number is one word long, so 4 bytes total!
	ti = (read_bits(bitcompression)) * 4;

	// read the onTime and offTime from the program memory
	ontime = pgm_read_word(time_ptr+ti);  // read word 1 - ontime
	offtime = pgm_read_word(time_ptr+ti+2);  // read word 2 - offtime

	// transmit this codeElement (ontime and offtime)
	xmitCodeElement(ontime, offtime, (freq!=0));  
      } 
      
      //Flush remaining bits, so that next code starts
      //with a fresh set of 8 bits.
      bitsleft_r=0;	

      // delay 250 milliseconds before transmitting next POWER code
      delay_ten_us(25000);
      
      // visible indication that a code has been output.
      quickflashLED(); 
    }
  } while (Loop == 1);
  
  // We are done, no need for a watchdog timer anymore
  wdt_disable();

  // flash the visible LED on PB0  4 times to indicate that we're done
  delay_ten_us(65500); // wait maxtime 
  delay_ten_us(65500); // wait maxtime 
  quickflashLEDx(4);

  tvbgone_sleep();
}
예제 #28
0
파일: ps.cpp 프로젝트: emericg/MiniVideo
/*!
 * \brief Parse a pack header structure.
 * \param *bitstr The bitstream to use.
 * \param *pack_header A pointer to a pack_header structure.
 * \return 1 if succeed, 0 otherwise.
 *
 * From 'ISO/IEC 13818-1' specification:
 * 2.5.3.3 Pack layer of Program Stream.
 * Table 2-33 – Program Stream pack header
 */
static int parse_pack_header(Bitstream_t *bitstr, PesHeader_t *header, PackHeader_t *packet)
{
    TRACE_INFO(MPS, BLD_GREEN "parse_pack_header()" CLR_RESET " @ %lli",
               header->offset_start);

    int retcode = SUCCESS;

    // Pack Headers do not have lengh field, rewind 2 bytes
    rewind_bits(bitstr, 16);

    if (read_bits(bitstr, 2) != 1)
    {
        TRACE_ERROR(MPS, "wrong 'marker_bits'");
        return FAILURE;
    }

    packet->system_clock_reference_base = read_bits(bitstr, 3) << 30;
    MARKER_BIT
    packet->system_clock_reference_base += read_bits(bitstr, 15) << 15;
    MARKER_BIT
    packet->system_clock_reference_base += read_bits(bitstr, 15);
    MARKER_BIT
    packet->system_clock_reference_extension = read_bits(bitstr, 9);
    MARKER_BIT
    packet->program_mux_rate = read_bits(bitstr, 22);
    MARKER_BIT
    MARKER_BIT
    /*unsigned reserved =*/ read_bits(bitstr, 5);

    packet->pack_stuffing_length = read_bits(bitstr, 3);

    // Stuffing
    for (uint8_t i = 0; i < packet->pack_stuffing_length; i++)
    {
        if (read_bits(bitstr, 8) != 0xFF)
        {
            TRACE_ERROR(MPS, "Wrong 'stuffing_byte'");
            return FAILURE;
        }
    }

    // System header // TODO split into its own function?
    if (next_bits(bitstr, 32) == 0x000001BB)
    {
        TRACE_INFO(MPS, BLD_GREEN "parse_system_header()" CLR_RESET " @ %lli",
                   bitstream_get_absolute_byte_offset(bitstr) - 4);
        skip_bits(bitstr, 48); // start code + size

        SystemHeader_t system_header;

        MARKER_BIT
        system_header.rate_bound = read_bits(bitstr, 22);
        MARKER_BIT
        system_header.audio_bound = read_bits(bitstr, 6);
        system_header.fixed_flag = read_bits(bitstr, 1);
        system_header.CSPS_flag = read_bits(bitstr, 1);
        system_header.system_audio_lock_flag = read_bits(bitstr, 1);
        system_header.system_video_lock_flag = read_bits(bitstr, 1);
        MARKER_BIT
        system_header.video_bound = read_bits(bitstr, 5);
        system_header.packet_rate_restriction_flag = read_bits(bitstr, 1);

        /*unsigned reserved_bits =*/ read_bits(bitstr, 7);

        // stack it?
        while (next_bit(bitstr) == 1)
        {
            system_header.stream_id = read_bits(bitstr, 8);
            MARKER_BIT
            MARKER_BIT
            system_header.PSTD_buffer_bound_scale = read_bits(bitstr, 1);
            system_header.PSTD_buffer_size_bound = read_bits(bitstr, 13);
        }
    }
    else
    {
        TRACE_2(MPS, " > No system_header()");
    }

    // Pack header have no length field, so we just have to parse them correctly
    header->offset_end = bitstream_get_absolute_byte_offset(bitstr);
    header->payload_length = header->offset_end - header->offset_start - 4;

    return retcode;
}
예제 #29
0
static void read_internate_code(int* code)
{
	char c[16] = {0};
	read_bits(c, 2 * 8);
	sscanf(c, "%02x", code);
}
예제 #30
0
// Read unsigned integer with bnum bits length.  Basically an
// alias for read_bits().
uint64_t u(struct bitstream *bstr, unsigned bnum)
{
    return read_bits(bstr, bnum);
}