Exemple #1
0
uint8_t * get_nal(uint32_t *len, uint8_t **offset, uint8_t *start, uint32_t total)
{
    uint32_t info;
    uint8_t *q ;
    uint8_t *p  =  *offset;
    *len = 0;

    while(1) {
        info =  find_start_code(p, 3);
        if (info == 1)
            break;
        p++;
        if ((p - start) >= total)
            return NULL;
    }
    q = p + 4;
    p = q;
    while(1) {
        info =  find_start_code(p, 3);
        if (info == 1)
            break;
        p++;
        if ((p - start) >= total)
            return NULL;
    }
    
    *len = (p - q);
    *offset = p;
    return q;
}
uint32_t handle_mpeg4AVC(uint8_t* data, uint32_t *input_size){
    uint32_t slice_type,nal_size,inp_size;
    uint8_t *nal_data;
    int nal_type,sc_type;
    inp_size=*input_size;
    /**/
    sc_type = find_start_code(data);
    data+=sc_type;
    *input_size=(*input_size)+sc_type;
    nal_size = get_nal_mem(data, 188-(*input_size));
    nal_data = data;
    data+=nal_size;
    *input_size=(*input_size)+nal_size;
	
    nal_type = get_nal_type(nal_data, nal_size);

    switch(nal_type){
	case AVC_NALU_IDR_SLICE:
	    slice_type= 1;
	    break;
	case AVC_NALU_NON_IDR_SLICE:
	    slice_type= 2;
	    break;
	default:
	    slice_type= 0;
	    break;
    }

    return slice_type;
}
Exemple #3
0
size_t mpeg_bitstream_parse(mpeg_bitstream_t* packet, caption_frame_t* frame, const uint8_t* data, size_t size, unsigned stream_type, double dts, double cts)
{
    if (MAX_NALU_SIZE <= packet->size) {
        packet->status = LIBCAPTION_ERROR;
        // fprintf(stderr, "LIBCAPTION_ERROR\n");
        return 0;
    }

    // consume upto MAX_NALU_SIZE bytes
    if (MAX_NALU_SIZE <= packet->size + size) {
        size = MAX_NALU_SIZE - packet->size;
    }

    sei_t sei;
    size_t header_size, scpos;
    packet->status = LIBCAPTION_OK;
    memcpy(&packet->data[packet->size], data, size);
    packet->size += size;

    while (packet->status == LIBCAPTION_OK && 0 < (scpos = find_start_code(&packet->data[0], packet->size))) {
        switch (mpeg_bitstream_packet_type(packet, stream_type)) {
        default:
            break;
        case H262_SEI_PACKET:
            header_size = 4;
            if (STREAM_TYPE_H262 == stream_type && scpos > header_size) {
                cea708_t* cea708 = _mpeg_bitstream_cea708_emplace_back(packet, dts + cts);
                packet->status = libcaption_status_update(packet->status, cea708_parse_h262(&packet->data[header_size], scpos - header_size, cea708));
                _mpeg_bitstream_cea708_sort_flush(packet, frame, dts);
            }
            break;
        case H264_SEI_PACKET:
        case H265_SEI_PACKET:
            header_size = STREAM_TYPE_H264 == stream_type ? 4 : STREAM_TYPE_H265 == stream_type ? 5 : 0;
            if (header_size && scpos > header_size) {
                packet->status = libcaption_status_update(packet->status, sei_parse(&sei, &packet->data[header_size], scpos - header_size, dts + cts));
                for (sei_message_t* msg = sei_message_head(&sei); msg; msg = sei_message_next(msg)) {
                    if (sei_type_user_data_registered_itu_t_t35 == sei_message_type(msg)) {
                        cea708_t* cea708 = _mpeg_bitstream_cea708_emplace_back(packet, dts + cts);
                        packet->status = libcaption_status_update(packet->status, cea708_parse_h264(sei_message_data(msg), sei_message_size(msg), cea708));
                        _mpeg_bitstream_cea708_sort_flush(packet, frame, dts);
                    }
                }
                sei_free(&sei);
            }
            break;
        }

        packet->size -= scpos;
        memmove(&packet->data[0], &packet->data[scpos], packet->size);
    }

    return size;
}
Exemple #4
0
inline void send_data_for_channel(int chn, const FHADV_VIDEO_FRM_INFO_t *info, const FH_ADDR data, const FH_SINT32 len)
{
    int i     = 0;
    unsigned char *pos = data;
    unsigned char *end = data + len;
    int rest  = len;
    unsigned char *next_start;

#ifdef FH_USING_RTSP
    struct rtsp_server_context *server = g_rtsp_servers[chn];
#else
    struct vlcview_enc_stream_element stream_element;

    stream_element.frame_type = info->key_frame ? VLCVIEW_ENC_H264_I_FRAME : VLCVIEW_ENC_H264_P_FRAME;
    stream_element.frame_len  = len;
    stream_element.time_stamp = info->ts;
    stream_element.nalu_count = 0;
#endif

    do
    {
        next_start = find_start_code(pos + 4, rest - 4);
        if (next_start)
        {
            #ifdef FH_USING_RTSP
            rtp_push_data(server, pos, next_start - pos, info->ts);
            #else
            stream_element.nalu[i].start = pos;
            stream_element.nalu[i].len   = next_start - pos;
            stream_element.nalu_count++;
            #endif
            i++;
            rest = rest - (next_start - pos);
            pos  = next_start;
        }
        else
        { /* reach the end of data */
            #ifdef FH_USING_RTSP
            rtp_push_data(server, pos, end - pos, info->ts);
            #else
            stream_element.nalu[i].start = pos;
            stream_element.nalu[i].len   = end - pos;
            stream_element.nalu_count++;
            #endif
        }
    } while (next_start != NULL);

#ifndef FH_USING_RTSP
    vlcview_pes_stream_pack(chn, stream_element);
#endif
}
Exemple #5
0
static bool looksLikeMPEG( unsigned char const *inData, unsigned long inSize )
{
   unsigned long state = 0xFF ;
   if( find_start_code( inData, inSize, state ) )
   {
      return (    state == PACK_START_CODE 
               || state == SYSTEM_HEADER_START_CODE 
               || (state >= 0x1e0 && state <= 0x1ef) 
               || (state >= 0x1c0 && state <= 0x1df) 
               || state == PRIVATE_STREAM_2 
               || state == PROGRAM_STREAM_MAP 
               || state == PRIVATE_STREAM_1 
               || state == PADDING_STREAM );
   }
   else
      return false ;
}
Exemple #6
0
bool CVC1BitstreamParser::vc1_parse_frame(const uint8_t *buf, const uint8_t *buf_end, bool sequence_only)
{
  uint32_t state = -1;
  for (;;)
  {
    buf = find_start_code(buf, buf_end, &state);
    if (buf >= buf_end)
      break;
    if (buf[-1] == VC1_SEQUENCE)
    {
      if (m_Profile != VC1_PROFILE_NOPROFILE)
        return false;
      CBitstreamReader br(buf, buf_end - buf);
      // Read the profile
      m_Profile = static_cast<uint8_t>(br.ReadBits(2));
      if (m_Profile == VC1_PROFILE_ADVANCED)
      {
        br.SkipBits(39);
        m_AdvInterlace = br.ReadBits(1);
      }
      else
      {
        br.SkipBits(22);

        m_SimpleSkipBits = 2;
        if (br.ReadBits(1)) //rangered
          ++m_SimpleSkipBits;

        m_MaxBFrames = br.ReadBits(3);

        br.SkipBits(2); // quantizer
        if (br.ReadBits(1)) //finterpflag
          ++m_SimpleSkipBits;
      }
      if (sequence_only)
        return true;
    }
    else if (buf[-1] == VC1_FRAME)
    {
      CBitstreamReader br(buf, buf_end - buf);

      if (sequence_only)
        return false;
      if (m_Profile == VC1_PROFILE_ADVANCED)
      {
        uint8_t fcm;
        if (m_AdvInterlace) {
          fcm = br.ReadBits(1);
          if (fcm)
            fcm = br.ReadBits(1) + 1;
        }
        else
          fcm = VC1_FRAME_PROGRESSIVE;
        if (fcm == VC1_FIELD_INTERLACE) {
          uint8_t pic = br.ReadBits(3);
          return pic == 0x00 || pic == 0x01;
        }
        else
        {
          uint8_t pic(0);
          while (pic < 4 && br.ReadBits(1))++pic;
          return pic == 2;
        }
        return false;
      }
      else if (m_Profile != VC1_PROFILE_NOPROFILE)
      {
        br.SkipBits(m_SimpleSkipBits); // quantizer
        uint8_t pic(br.ReadBits(1));
        if (m_MaxBFrames) {
          if (!pic) {
            pic = br.ReadBits(1);
            return pic != 0;
          }
          else
            return false;
        }
        else
          return pic != 0;
      }
      else
        break;
    }
  }
  return false;
}
Exemple #7
0
static int vdec_h264_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs,
			    struct vdec_fb *fb, bool *res_chg)
{
	struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
	struct vdec_vpu_inst *vpu = &inst->vpu;
	int nal_start_idx = 0;
	int err = 0;
	unsigned int nal_start;
	unsigned int nal_type;
	unsigned char *buf;
	unsigned int buf_sz;
	unsigned int data[2];
	uint64_t vdec_fb_va = (u64)(uintptr_t)fb;
	uint64_t y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
	uint64_t c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;

	mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
			 ++inst->num_nalu, y_fb_dma, c_fb_dma, fb);

	/* bs NULL means flush decoder */
	if (bs == NULL)
		return vpu_dec_reset(vpu);

	buf = (unsigned char *)bs->va;
	buf_sz = bs->size;
	nal_start_idx = find_start_code(buf, buf_sz);
	if (nal_start_idx < 0)
		goto err_free_fb_out;

	nal_start = buf[nal_start_idx];
	nal_type = NAL_TYPE(buf[nal_start_idx]);
	mtk_vcodec_debug(inst, "\n + NALU[%d] type %d +\n", inst->num_nalu,
			 nal_type);

	if (nal_type == NAL_H264_PPS) {
		buf_sz -= nal_start_idx;
		if (buf_sz > HDR_PARSING_BUF_SZ) {
			err = -EILSEQ;
			goto err_free_fb_out;
		}
		memcpy(inst->vsi->hdr_buf, buf + nal_start_idx, buf_sz);
	}

	inst->vsi->dec.bs_dma = (uint64_t)bs->dma_addr;
	inst->vsi->dec.y_fb_dma = y_fb_dma;
	inst->vsi->dec.c_fb_dma = c_fb_dma;
	inst->vsi->dec.vdec_fb_va = vdec_fb_va;

	data[0] = buf_sz;
	data[1] = nal_start;
	err = vpu_dec_start(vpu, data, 2);
	if (err)
		goto err_free_fb_out;

	*res_chg = inst->vsi->dec.resolution_changed;
	if (*res_chg) {
		struct vdec_pic_info pic;

		mtk_vcodec_debug(inst, "- resolution changed -");
		get_pic_info(inst, &pic);

		if (inst->vsi->dec.realloc_mv_buf) {
			err = alloc_mv_buf(inst, &pic);
			if (err)
				goto err_free_fb_out;
		}
	}

	if (nal_type == NAL_NON_IDR_SLICE || nal_type == NAL_IDR_SLICE) {
		/* wait decoder done interrupt */
		err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
						   MTK_INST_IRQ_RECEIVED,
						   WAIT_INTR_TIMEOUT_MS);
		if (err)
			goto err_free_fb_out;

		vpu_dec_end(vpu);
	}

	mtk_vcodec_debug(inst, "\n - NALU[%d] type=%d -\n", inst->num_nalu,
			 nal_type);
	return 0;

err_free_fb_out:
	put_fb_to_free(inst, fb);
	mtk_vcodec_err(inst, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err);
	return err;
}