예제 #1
0
void _write_ff_coded_number(bs_t* b, int n)
{
    while (1)
    {
        if (n > 0xff)
        {
            bs_write_u8(b, 0xff);
            n -= 0xff;
        }
        else
        {
            bs_write_u8(b, n);
            break;
        }
    }
}
예제 #2
0
// D.1 SEI payload syntax
void write_sei_payload( h264_stream_t* h, bs_t* b )
{
    sei_t* s = h->sei;
    
    int i;
    switch( s->payloadType )
    {
        case SEI_TYPE_SCALABILITY_INFO:
            if( 0 )
            {
                s->sei_svc = (sei_scalability_info_t*)calloc( 1, sizeof(sei_scalability_info_t) );
            }
            write_sei_scalability_info( h, b );
            break;
        default:
            if( 0 )
            {
                s->data = (uint8_t*)calloc(1, s->payloadSize);
            }
            
            for ( i = 0; i < s->payloadSize; i++ )
                bs_write_u8(b, s->data[i]);
    }
    
    //if( 0 )
    //    read_sei_end_bits(h, b);
}
예제 #3
0
int write_avcc(avcc_t* avcc, h264_stream_t* h, bs_t* b)
{
  bs_write_u8(b, 1); // configurationVersion = 1;
  bs_write_u8(b, avcc->AVCProfileIndication);
  bs_write_u8(b, avcc->profile_compatibility);
  bs_write_u8(b, avcc->AVCLevelIndication);
  bs_write_u(b, 6, 0x3F); // reserved = '111111'b;
  bs_write_u(b, 2, avcc->lengthSizeMinusOne);
  bs_write_u(b, 3, 0x07); // reserved = '111'b;

  bs_write_u(b, 5, avcc->numOfSequenceParameterSets);
  int i;
  for (i = 0; i < avcc->numOfSequenceParameterSets; i++)
  {
    int max_len = 1024; // FIXME
    uint8_t* buf = (uint8_t*)malloc(max_len);
    h->nal->nal_ref_idc = 3; // NAL_REF_IDC_PRIORITY_HIGHEST;
    h->nal->nal_unit_type = NAL_UNIT_TYPE_SPS;
    h->sps = avcc->sps_table[i];
    int len = write_nal_unit(h, buf, max_len);
    if (len < 0) { free(buf); continue; } // TODO report errors
    int sequenceParameterSetLength = len;
    bs_write_u(b, 16, sequenceParameterSetLength);
    bs_write_bytes(b, buf, len);
    free(buf);
  }

  bs_write_u(b, 8, avcc->numOfPictureParameterSets);
  for (i = 0; i < avcc->numOfPictureParameterSets; i++)
  {
    int max_len = 1024; // FIXME
    uint8_t* buf = (uint8_t*)malloc(max_len);
    h->nal->nal_ref_idc = 3; // NAL_REF_IDC_PRIORITY_HIGHEST;
    h->nal->nal_unit_type = NAL_UNIT_TYPE_PPS;
    h->pps = avcc->pps_table[i];
    int len = write_nal_unit(h, buf, max_len);
    if (len < 0) { free(buf); continue; } // TODO report errors
    int pictureParameterSetLength = len;
    bs_write_u(b, 16, pictureParameterSetLength);
    bs_write_bytes(b, buf, len);
    free(buf);
  }

  if (bs_overrun(b)) { return -1; }
  return bs_pos(b);
}
int pes_header_write(pes_header_t *ph, bs_t *b) {

	// TODO: add support for PES-level stuffing

	int start_pos = bs_pos(b);
	bs_write_u24(b, PES_PACKET_START_CODE_PREFIX);
	bs_write_u8(b, ph->stream_id);
	bs_write_u16(b, ph->PES_packet_length);

	if (HAS_PES_HEADER(ph->stream_id)) {

		bs_write_u(b, 2, 0x02);
		bs_write_u(b, 2, ph->PES_scrambling_control);
		bs_write_u1(b, ph->PES_priority);
		bs_write_u1(b, ph->data_alignment_indicator);
		bs_write_u1(b, ph->copyright);
		bs_write_u1(b, ph->original_or_copy);

		bs_write_u(b, 2, ph->PTS_DTS_flags);
		bs_write_u1(b, ph->ESCR_flag);
		bs_write_u1(b, ph->ES_rate_flag);
		bs_write_u1(b, ph->DSM_trick_mode_flag);
		bs_write_u1(b, ph->additional_copy_info_flag);
		bs_write_u1(b, ph->PES_CRC_flag);
		bs_write_u1(b, ph->PES_extension_flag);

		bs_write_u8(b, ph->PES_header_data_length);

		if (ph->PTS_DTS_flags & PES_PTS_FLAG) {
			bs_write_u(b, 4, 0x02);
			bs_write_90khz_timestamp(b, ph->PTS);
		}

		if (ph->PTS_DTS_flags & PES_DTS_FLAG) {
			bs_write_u(b, 4, 0x01);
			bs_write_90khz_timestamp(b, ph->DTS);
		}

		if (ph->ESCR_flag) {
			bs_write_reserved(b, 2);
			bs_write_90khz_timestamp(b, ph->ESCR_base);
			bs_write_u(b, 9, ph->ESCR_extension);
			bs_write_marker_bit(b);
		}
		if (ph->ES_rate_flag) {
			bs_write_marker_bit(b);
			bs_write_u(b, 22, ph->ES_rate);
			bs_write_marker_bit(b);
		}
		if (ph->DSM_trick_mode_flag) {
			bs_write_u(b, 3, ph->trick_mode_control);

			switch (ph->trick_mode_control) {
			case PES_DSM_TRICK_MODE_CTL_FAST_FORWARD:
			case PES_DSM_TRICK_MODE_CTL_FAST_REVERSE:
				bs_write_u(b, 2, ph->field_id);
				bs_write_u1(b, ph->intra_slice_refresh);
				bs_write_u(b, 2, ph->frequency_truncation);

				break;

			case PES_DSM_TRICK_MODE_CTL_SLOW_MOTION:
			case PES_DSM_TRICK_MODE_CTL_SLOW_REVERSE:
				bs_write_u(b, 5, ph->rep_cntrl);
				break;

			case PES_DSM_TRICK_MODE_CTL_FREEZE_FRAME:
				bs_write_u(b, 2, ph->field_id);
				bs_write_reserved(b, 3);
				break;

			default:
				bs_write_reserved(b, 5);
				break;
			}
		}

		if (ph->additional_copy_info_flag) {
			bs_write_marker_bit(b);
			bs_write_u(b, 7, ph->additional_copy_info);
		}
		if (ph->PES_CRC_flag) {
			bs_write_u16(b, ph->previous_PES_packet_CRC);
		}
		if (ph->PES_extension_flag) {
			bs_write_u1(b, ph->PES_private_data_flag);
			bs_write_u1(b, 0); // pack_header not supported
			bs_write_u1(b, ph->program_packet_sequence_counter_flag);
			bs_write_u1(b, ph->PSTD_buffer_flag);
			bs_write_reserved(b, 3);
			bs_write_u1(b, ph->PES_extension_flag_2);

			if (ph->PES_private_data_flag) {
				bs_write_bytes(b, ph->PES_private_data, 16);
			}

			if (ph->program_packet_sequence_counter_flag) {
				bs_write_marker_bit(b);
				bs_write_u(b, 7, ph->program_packet_sequence_counter);
				bs_write_marker_bit(b);
				bs_write_u1(b, ph->MPEG1_MPEG2_identifier);
				bs_write_u(b, 6, ph->original_stuff_length);
			}

			if (ph->PSTD_buffer_flag) {
				bs_write_u(b, 2, 0x01);
				bs_write_u1(b, ph->PSTD_buffer_scale);
				bs_write_u(b, 13, ph->PSTD_buffer_size);
			}

			if (ph->PES_extension_flag_2) {
				bs_write_marker_bit(b);
				bs_write_u(b, 7, ph->PES_extension_field_length);
				bs_write_u1(b, ph->stream_id_extension_flag);

				if (!ph->stream_id_extension_flag) {
					bs_write_u(b, 7, ph->stream_id_extension);
				} else {
					bs_write_reserved(b, 6);
					bs_write_u1(b, ph->tref_extension_flag);

					if (ph->tref_extension_flag) {
						bs_write_reserved(b, 4);
						bs_write_90khz_timestamp(b, ph->TREF);
					}
				}
			}
		}
	}
	return (bs_pos(b) - start_pos);
}