int Write_AUD_NALU( VideoParameters *p_Vid ) { int RBSPlen = 0; int len; byte rbsp[MAXRBSPSIZE]; NALU_t *nalu = AllocNALU( MAXNALUSIZE ); switch( p_Vid->type ) { case I_SLICE: p_Vid->primary_pic_type = 0; break; case P_SLICE: p_Vid->primary_pic_type = 1; break; case B_SLICE: p_Vid->primary_pic_type = 2; break; } RBSPlen = 1; rbsp[0] = (byte) (p_Vid->primary_pic_type << 5); rbsp[0] |= (1 << 4); // write RBSP into NALU RBSPtoNALU( rbsp, nalu, RBSPlen, NALU_TYPE_AUD, NALU_PRIORITY_DISPOSABLE, 1 ); // write NALU into bitstream len = p_Vid->WriteNALU( p_Vid, nalu, p_Vid->f_out ); FreeNALU( nalu ); return len; }
int Write_Filler_Data_NALU( VideoParameters *p_Vid, int num_bytes ) { int RBSPlen = num_bytes - 1; int len, bytes_written = 0; byte rbsp[MAXRBSPSIZE]; byte filler_byte = (byte)0xFF; byte trailing_byte = (byte)0x80; NALU_t *nalu = AllocNALU( MAXNALUSIZE ); num_bytes = iClip3( 1, (MAXRBSPSIZE - 2), num_bytes ); assert( num_bytes > 0 && num_bytes < (MAXRBSPSIZE - 1) ); num_bytes = imax( 2, num_bytes ); // one byte for the NAL header and one for the rbsp trailing byte if ( RBSPlen > 1 ) { while ( bytes_written < (RBSPlen - 1) ) { rbsp[ bytes_written++ ] = filler_byte; } } rbsp[ bytes_written++ ] = trailing_byte; // rbsp_trailing_bits assert( num_bytes == (bytes_written + 1) ); // write RBSP into NALU RBSPtoNALU( rbsp, nalu, RBSPlen, NALU_TYPE_FILL, NALU_PRIORITY_DISPOSABLE, 1 ); // write NALU into bitstream len = p_Vid->WriteNALU( p_Vid, nalu, p_Vid->f_out ); p_Vid->bytes_in_picture += (nalu->len + 1); FreeNALU( nalu ); return len; }
/*! *********************************************************************** * \brief * Allocate the Video Parameters structure * \par Output: * Video Parameters VideoParameters *p_Vid *********************************************************************** */ static void alloc_video_params( VideoParameters **p_Vid) { int i; if ((*p_Vid = (VideoParameters *) calloc(1, sizeof(VideoParameters)))==NULL) no_mem_exit("alloc_video_params: p_Vid"); if (((*p_Vid)->old_slice = (OldSliceParams *) calloc(1, sizeof(OldSliceParams)))==NULL) no_mem_exit("alloc_video_params: p_Vid->old_slice"); if (((*p_Vid)->snr = (SNRParameters *)calloc(1, sizeof(SNRParameters)))==NULL) no_mem_exit("alloc_video_params: p_Vid->snr"); // Allocate new dpb buffer for (i = 0; i < MAX_NUM_DPB_LAYERS; i++) { if(((*p_Vid)->p_EncodePar[i] = (CodingParameters *)calloc(1, sizeof(CodingParameters))) == NULL) no_mem_exit("alloc_video_params:p_Vid->p_EncodePar[i]"); ((*p_Vid)->p_EncodePar[i])->layer_id = i; } (*p_Vid)->global_init_done[0] = (*p_Vid)->global_init_done[1] = 0; if(((*p_Vid)->ppSliceList = (Slice **) calloc(MAX_NUM_DECSLICES, sizeof(Slice *))) == NULL) { no_mem_exit("alloc_video_params: p_Vid->ppSliceList"); } (*p_Vid)->iNumOfSlicesAllocated = MAX_NUM_DECSLICES; (*p_Vid)->pNextSlice = NULL; (*p_Vid)->nalu = AllocNALU(MAX_CODED_FRAME_SIZE); (*p_Vid)->pNextPPS = AllocPPS(); (*p_Vid)->first_sps = TRUE; }
/*! *********************************************************************** * \brief * Allocate the Video Parameters structure * \par Output: * Video Parameters VideoParameters *p_Vid *********************************************************************** */ static void alloc_video_params( VideoParameters **p_Vid) { int i; if ((*p_Vid = (VideoParameters *) mem_calloc(1, sizeof(VideoParameters)))==NULL) no_mem_exit("alloc_video_params: p_Vid"); if (((*p_Vid)->old_slice = (OldSliceParams *) mem_calloc(1, sizeof(OldSliceParams)))==NULL) no_mem_exit("alloc_video_params: p_Vid->old_slice"); if (((*p_Vid)->snr = (SNRParameters *)mem_calloc(1, sizeof(SNRParameters)))==NULL) no_mem_exit("alloc_video_params: p_Vid->snr"); // Allocate new dpb buffer for (i = 0; i < MAX_NUM_DPB_LAYERS; i++) { if (((*p_Vid)->p_Dpb_layer[i] = (DecodedPictureBuffer*)mem_calloc(1, sizeof(DecodedPictureBuffer)))==NULL) no_mem_exit("alloc_video_params: p_Vid->p_Dpb_layer[i]"); (*p_Vid)->p_Dpb_layer[i]->layer_id = i; reset_dpb(*p_Vid, (*p_Vid)->p_Dpb_layer[i]); if(((*p_Vid)->p_EncodePar[i] = (CodingParameters *)mem_calloc(1, sizeof(CodingParameters))) == NULL) no_mem_exit("alloc_video_params:p_Vid->p_EncodePar[i]"); ((*p_Vid)->p_EncodePar[i])->layer_id = i; if(((*p_Vid)->p_LayerPar[i] = (LayerParameters *)mem_calloc(1, sizeof(LayerParameters))) == NULL) no_mem_exit("alloc_video_params:p_Vid->p_LayerPar[i]"); ((*p_Vid)->p_LayerPar[i])->layer_id = i; } (*p_Vid)->global_init_done[0] = (*p_Vid)->global_init_done[1] = 0; #if (ENABLE_OUTPUT_TONEMAPPING) if (((*p_Vid)->seiToneMapping = (ToneMappingSEI*)mem_calloc(1, sizeof(ToneMappingSEI)))==NULL) no_mem_exit("alloc_video_params: (*p_Vid)->seiToneMapping"); #endif if(((*p_Vid)->ppSliceList = (Slice **) mem_calloc(MAX_NUM_DECSLICES, sizeof(Slice *))) == NULL) { no_mem_exit("alloc_video_params: p_Vid->ppSliceList"); } (*p_Vid)->iNumOfSlicesAllocated = MAX_NUM_DECSLICES; //(*p_Vid)->currentSlice = NULL; (*p_Vid)->pNextSlice = NULL; (*p_Vid)->nalu = AllocNALU(MAX_CODED_FRAME_SIZE); (*p_Vid)->nalu0 = AllocNALU(MAX_CODED_FRAME_SIZE); (*p_Vid)->nalu1 = AllocNALU(MAX_CODED_FRAME_SIZE); (*p_Vid)->pDecOuputPic = (DecodedPicList *)mem_calloc(1, sizeof(DecodedPicList)); (*p_Vid)->pNextPPS = AllocPPS(); (*p_Vid)->first_sps = TRUE; }
NALU_t *GeneratePic_parameter_set_NALU(int PPS_id) { NALU_t *n = AllocNALU(64000); int RBSPlen = 0; int NALUlen; byte rbsp[MAXRBSPSIZE]; RBSPlen = GeneratePic_parameter_set_rbsp (&PicParSet[PPS_id], rbsp); NALUlen = RBSPtoNALU (rbsp, n, RBSPlen, NALU_TYPE_PPS, NALU_PRIORITY_HIGHEST, 0, 1); n->startcodeprefix_len = 4; return n; }
NALU_t *GenerateSeq_parameter_set_NALU () { NALU_t *n = AllocNALU(64000); int RBSPlen = 0; int NALUlen; byte rbsp[MAXRBSPSIZE]; RBSPlen = GenerateSeq_parameter_set_rbsp (active_sps, rbsp); NALUlen = RBSPtoNALU (rbsp, n, RBSPlen, NALU_TYPE_SPS, NALU_PRIORITY_HIGHEST, 0, 1); n->startcodeprefix_len = 4; return n; }
NALU_t *GeneratePic_parameter_set_NALU() { NALU_t *n = AllocNALU(64000); int RBSPlen = 0; int NALUlen; byte rbsp[MAXRBSPSIZE]; RBSPlen = GeneratePic_parameter_set_rbsp (active_pps, rbsp); //++ 参见标准7.3.2.2、7.4.2.2节 NALUlen = RBSPtoNALU (rbsp, n, RBSPlen, NALU_TYPE_PPS, NALU_PRIORITY_HIGHEST, 0, 1); n->startcodeprefix_len = 4; return n; }
/*! ************************************************************************************* * \brief * NALU_t *GeneratePic_parameter_set_NALU (); * * \note * Uses the global variables through FillParameterSetStructures() * * \return * A NALU containing the Picture Parameter Set * ************************************************************************************* */ NALU_t *GeneratePic_parameter_set_NALU(pic_parameter_set_rbsp_t *active_pps) { NALU_t *n = AllocNALU(64000); t_sint32 RBSPlen = 0; byte *rbsp = (byte*)NULL; void * vfm_memory_ctxt = my_vfm_memory_ctxt; /*byte rbsp[MAXRBSPSIZE]; */ rbsp = (byte *)malloc_(MAXRBSPSIZE * sizeof(char)); // rbsp = (byte *)alloca(MAXRBSPSIZE * sizeof(char)); RBSPlen = GeneratePic_parameter_set_rbsp (active_pps, (char *)rbsp); RBSPtoNALU ((char *)rbsp, n, RBSPlen, NALU_TYPE_PPS, NALU_PRIORITY_HIGHEST, 0, 1); n->startcodeprefix_len = 4; free(rbsp); return n; }
/*! *********************************************************************** * \brief * Allocate the Image structure * \par Output: * Image Parameters VideoParameters *p_Vid *********************************************************************** */ static void alloc_img( VideoParameters **p_Vid) { if ((*p_Vid = (VideoParameters *) calloc(1, sizeof(VideoParameters)))==NULL) no_mem_exit("alloc_img: p_Vid"); if (((*p_Vid)->old_slice = (OldSliceParams *) calloc(1, sizeof(OldSliceParams)))==NULL) no_mem_exit("alloc_img: p_Vid->old_slice"); if (((*p_Vid)->snr = (SNRParameters *)calloc(1, sizeof(SNRParameters)))==NULL) no_mem_exit("alloc_img: p_Vid->snr"); if (((*p_Vid)->p_Dpb = (DecodedPictureBuffer*)calloc(1, sizeof(DecodedPictureBuffer)))==NULL) no_mem_exit("alloc_img: p_Vid->p_Dpb"); (*p_Vid)->p_Dpb->p_Vid = (*p_Vid); (*p_Vid)->p_Dpb->init_done = 0; (*p_Vid)->global_init_done = 0; #if (ENABLE_OUTPUT_TONEMAPPING) if (((*p_Vid)->seiToneMapping = (ToneMappingSEI*)calloc(1, sizeof(ToneMappingSEI)))==NULL) no_mem_exit("alloc_img: (*p_Vid)->seiToneMapping"); #endif if(((*p_Vid)->ppSliceList = (Slice **) calloc(MAX_NUM_DECSLICES, sizeof(Slice *))) == NULL) { no_mem_exit("alloc_img: p_Vid->ppSliceList"); } (*p_Vid)->iNumOfSlicesAllocated = MAX_NUM_DECSLICES; //(*p_Vid)->currentSlice = NULL; (*p_Vid)->pNextSlice = NULL; (*p_Vid)->nalu = AllocNALU(MAX_CODED_FRAME_SIZE); (*p_Vid)->pDecOuputPic = (DecodedPicList *)calloc(1, sizeof(DecodedPicList)); (*p_Vid)->pNextPPS = AllocPPS(); }
int main(int argc, char **argv) { int Flag = TRUE; //long ftell_position;//, expected_slice_type; //int ret; NALU_t *nalu; h264_decoder* dec_params; char *ptr; ptr = ( char*)malloc(10 * sizeof(char)); if ((dec_params = ( h264_decoder*)h264_malloc(1 * sizeof(h264_decoder)))==NULL) // if ((dec_params = ( h264_decoder*)h264_malloc(1 * 100))==NULL) { Flag=FALSE; } if ((dec_params->input = (InputParameters *)h264_malloc(1 * sizeof(InputParameters)))==NULL) { printf("main: input"); exit(0); } if ((dec_params->img = (ImageParameters *)h264_malloc(1 * sizeof(ImageParameters)))==NULL) { printf("main: img"); exit(0); } ////////// ADDED INITIALIZATIONS ////// dec_params->active_sps = NULL; dec_params->active_pps = NULL; dec_params->Co_located = NULL; dec_params->dec_picture = NULL; dec_params->global_init_done = 0; dec_params->dpb.init_done = 0; dec_params->img->DeblockCall = 0; // dec_params->img->structure = 0; dec_params->MapUnitToSliceGroupMap = NULL; dec_params->MbToSliceGroupMap = NULL; dec_params->img->errorConcealmentFlag = 0; // ERROR CONCEALMENT FLAG SET TO ZERO , NO ERROR CONCEALMENT dec_params->img->no_output_of_prior_pics_flag = -1; /////////////////////////////////////// Initializations(dec_params); Configure ( argc, argv,dec_params ); init_old_slice(dec_params); switch (dec_params->input->FileFormat) { case 0: OpenBitstreamFile (dec_params->input->infile,dec_params); break; case 1: OpenRTPFile (dec_params->input->infile,dec_params); break; default: printf ("Unsupported file format %d, exit\n", dec_params->input->FileFormat); } // Allocate Slice data struct malloc_slice(dec_params->input,dec_params->img,dec_params); init(dec_params->img,dec_params); dec_params->dec_picture = NULL; dec_params->dpb.init_done = 0; //dec_params->g_nFrame = 0; // init_out_buffer(dec_params); //dec_params->img->idr_psnr_number=dec_params->input->ref_offset; //dec_params->img->psnr_number=0; dec_params->img->number=0; dec_params->img->type = I_SLICE; dec_params->img->dec_ref_pic_marking_buffer = NULL; // B pictures dec_params->Bframe_ctr=0; // time for total decoding session dec_params->tot_time = 0; dec_params->nalu = AllocNALU(MAX_CODED_FRAME_SIZE,dec_params); nalu = dec_params->nalu; dec_params->dp = AllocPartition(1, dec_params,1024); dec_params->sps = AllocSPS(); dec_params->pps = AllocPPS(); { while ( decode_one_frame( dec_params ) != EOS ); } //report( dec_params->input, dec_params->img, dec_params->snr,dec_params,); report( dec_params->input, dec_params->img,dec_params); free_slice( dec_params->input,dec_params->img); FreeNALU(dec_params->nalu); FreePartition (dec_params->dp, 1); FreeSPS (dec_params->sps); if (dec_params->PicParSet[dec_params->pps->pic_parameter_set_id].Valid == TRUE && dec_params->PicParSet[dec_params->pps->pic_parameter_set_id].slice_group_id != NULL) { h264_free (dec_params->PicParSet[dec_params->pps->pic_parameter_set_id].slice_group_id); dec_params->PicParSet[dec_params->pps->pic_parameter_set_id].slice_group_id = NULL; } // IF FMO PRESENT if (dec_params->active_pps->num_slice_groups_minus1) { FmoFinit(dec_params); } FreePPS (dec_params->pps); free_global_buffers_baseline(dec_params); flush_dpb(dec_params); #ifdef PAIR_FIELDS_IN_OUTPUT flush_pending_output(dec_params->p_out); #endif CloseBitstreamFile(dec_params); //close(dec_params->p_out); fclose (dec_params->f_out); // fclose(p_out2); #if TRACE fclose(p_trace); #endif //ercClose(dec_params->erc_errorVar,dec_params); ercClose(dec_params); free_dpb(dec_params); // uninit_out_buffer(dec_params); free_colocated(dec_params); if(dec_params->dec_picture != NULL) { free (dec_params->dec_picture); dec_params->dec_picture = NULL; } if(dec_params->input != NULL) { h264_free (dec_params->input); dec_params->input = NULL; } if(dec_params->img != NULL) { h264_free (dec_params->img); dec_params->img = NULL; } if(dec_params != NULL) { h264_free (dec_params); dec_params = NULL; } return 0; }
/******************************************************************************************************************** RTP 各项参数初始化 1.初始化锁 2.分配音频打包所需的内存空间 *********************************************************************************************************************/ void rtp_build_init() { g_audio_puiNalBuf = AllocNALU(20000); return ; }
int rtp_send_file(int sockfd,struct sockaddr *addr) { printf("into the rtp_send_file...\n"); int rtp_number; //OpenBitstreamFile("./test.264");//打开264文件,并将文件指针赋给bits,在此修改文件名实现打开别的264文件。 OpenBitstreamFile("./slamtv60.264");//打开264文件,并将文件指针赋给bits,在此修改文件名实现打开别的264文件。 NALU_t *n; char* nalu_payload; char sendbuf[1500]; unsigned short seq_num =0; int bytes=0; float framerate=15; unsigned int timestamp_increse=0,ts_current=0; timestamp_increse=(unsigned int)(90000.0 / framerate); //+0.5); sleep(3); n = AllocNALU(80000000);//为结构体nalu_t及其成员buf分配空间。返回值为指向nalu_t存储空间的指针 sleep(3); printf("before the GetAnnexbNALU\n"); while(!feof(bits)) { GetAnnexbNALU(n);//每执行一次,文件的指针指向本次找到的NALU的末尾,下一个位置即为下个NALU的起始码0x000001 //dump(n);//输出NALU长度和TYPE memset(sendbuf,0,1500);//清空sendbuf;此时会将上次的时间戳清空,因此需要ts_current来保存上次的时间戳值 //rtp固定包头,为12字节,该句将sendbuf[0]的地址赋给rtp_hdr,以后对rtp_hdr的写入操作将直接写入sendbuf。 rtp_hdr =(RTP_FIXED_HEADER*)&sendbuf[0]; //设置RTP HEADER, rtp_hdr->payload = H264; //负载类型号, rtp_hdr->version = 2; //版本号,此版本固定为2 rtp_hdr->marker = 0; //标志位,由具体协议规定其值。 rtp_hdr->ssrc = htonl(10); //随机指定为10,并且在本RTP会话中全局唯一 // 当一个NALU小于1400字节的时候,采用一个单RTP包发送 if(n->len<=1400) { //设置rtp M 位; rtp_hdr->marker=1; rtp_hdr->seq_no = htons(seq_num ++); //序列号,每发送一个RTP包增1 //设置NALU HEADER,并将这个HEADER填入sendbuf[12] nalu_hdr =(NALU_HEADER*)&sendbuf[12]; //将sendbuf[12]的地址赋给nalu_hdr,之后对nalu_hdr的写入就将写入sendbuf中; nalu_hdr->F=n->forbidden_bit; nalu_hdr->NRI=n->nal_reference_idc>>5;//有效数据在n->nal_reference_idc的第6,7位,需要右移5位才能将其值赋给nalu_hdr->NRI。 nalu_hdr->TYPE=n->nal_unit_type; nalu_payload=&sendbuf[13];//同理将sendbuf[13]赋给nalu_payload memcpy(nalu_payload,n->buf+1,n->len-1);//去掉nalu头的nalu剩余内容写入sendbuf[13]开始的字符串。 ts_current=ts_current+timestamp_increse; rtp_hdr->timestamp=htonl(ts_current); bytes=n->len + 12 ; //获得sendbuf的长度,为nalu的长度(包含NALU头但除去起始前缀)加上rtp_header的固定长度12字节 // send( socket1, sendbuf, bytes, 0 );//发送rtp包 rtp_number = sendto(sockfd,sendbuf,bytes,0,addr,16); if(-1==rtp_number) { perror("len < 1400 rtp sendto error"); } else { printf("len < 1400 rtp_number = %d\n",rtp_number); } // Sleep(100); } else if(n->len>1400)
int main(int argc, char* argv[]) { //FILE *stream; //stream=fopen("Test.264", "wb"); OpenBitstreamFile("test2.h264");//打开264文件,并将文件指针赋给bits,在此修改文件名实现打开别的264文件。 NALU_t *n; char* nalu_payload; char sendbuf[1500]; unsigned short seq_num =0; //printf("seq_num=%d\n",seq_num);//added by int bytes=0; //InitWinsock(); //初始化套接字库 SOCKET socket1; struct sockaddr_in server; int len =sizeof(server); float framerate=25; unsigned int timestamp_increase=0,ts_current=0; timestamp_increase=(unsigned int)(90000.0 / framerate); //+0.5); server.sin_family=AF_INET; server.sin_port=htons(DEST_PORT); server.sin_addr.s_addr=inet_addr(DEST_IP); socket1=socket(AF_INET,SOCK_DGRAM,0); connect(socket1, (const struct sockaddr *)&server, len) ;//申请UDP套接字 n = AllocNALU(8000000);//为结构体nalu_t及其成员buf分配空间。返回值为指向nalu_t存储空间的指针 while(!feof(bits)) { GetAnnexbNALU(n);//每执行一次,文件的指针指向本次找到的NALU的末尾,下一个位置即为下个NALU的起始码0x000001 dump(n);//输出NALU长度和TYPE memset(sendbuf,0,1500);//清空sendbuf;此时会将上次的时间戳清空,因此需要ts_current来保存上次的时间戳值 //rtp固定包头,为12字节,该句将sendbuf[0]的地址赋给rtp_hdr,以后对rtp_hdr的写入操作将直接写入sendbuf。 rtp_hdr =(RTP_FIXED_HEADER*)&sendbuf[0]; //设置RTP HEADER, rtp_hdr->payload = H264; //负载类型号, rtp_hdr->version = 2; //版本号,此版本固定为2 rtp_hdr->marker = 0; //标志位,由具体协议规定其值。 rtp_hdr->ssrc = htonl(10); //随机指定为10,并且在本RTP会话中全局唯一 // 当一个NALU小于1400字节的时候,采用一个单RTP包发送 if(n->len<=1400) { //设置rtp M 位; rtp_hdr->marker=1; rtp_hdr->seq_no = htons(seq_num ++); //序列号,每发送一个RTP包增1 //设置NALU HEADER,并将这个HEADER填入sendbuf[12] nalu_hdr =(NALU_HEADER*)&sendbuf[12]; //将sendbuf[12]的地址赋给nalu_hdr,之后对nalu_hdr的写入就将写入sendbuf中; nalu_hdr->F=n->forbidden_bit; nalu_hdr->NRI=n->nal_reference_idc>>5;//有效数据在n->nal_reference_idc的第6,7位,需要右移5位才能将其值赋给nalu_hdr->NRI。 nalu_hdr->TYPE=n->nal_unit_type; nalu_payload=&sendbuf[13];//同理将sendbuf[13]赋给nalu_payload memcpy(nalu_payload,n->buf+1,n->len-1);//去掉nalu头的nalu剩余内容写入sendbuf[13]开始的字符串。 ts_current=ts_current+timestamp_increase; rtp_hdr->timestamp=htonl(ts_current); bytes=n->len + 13 ; //获得sendbuf的长度,为nalu的长度(包含NALU头但除去起始前缀)加上rtp_header的固定长度12字节 send( socket1, sendbuf, bytes, 0 );//发送rtp包 //sleep(1); //fwrite(sendbuf,bytes, 1, stream); } else if(n->len>1400)
/*! ************************************************************************ * \brief * Reads new slice from bit_stream ************************************************************************ */ int read_new_slice() { NALU_t *nalu = AllocNALU(MAX_CODED_FRAME_SIZE); int current_header; int ret; int BitsUsedByHeader; Slice *currSlice = img->currentSlice; Bitstream *currStream; int newframe; int slice_id_a, slice_id_b, slice_id_c; int redundant_pic_cnt_a, redundant_pic_cnt_b, redundant_pic_cnt_c; long ftell_position, expected_slice_type; // int i; expected_slice_type = NALU_TYPE_DPA; while (1) { ftell_position = ftell(bits); if (input->FileFormat == PAR_OF_ANNEXB) ret=GetAnnexbNALU (nalu); else ret=GetRTPNALU (nalu); NALUtoRBSP(nalu); // printf ("nalu->len %d\n", nalu->len); if (ret < 0) printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP"); if (ret == 0) { // printf ("read_new_slice: returning %s\n", "EOS"); if(expected_slice_type != NALU_TYPE_DPA) { /* oops... we found the next slice, go back! */ fseek(bits, ftell_position, SEEK_SET); FreeNALU(nalu); return current_header; } else return EOS; } // Got a NALU if (nalu->forbidden_bit) { printf ("Found NALU w/ forbidden_bit set, bit error? Let's try...\n"); } switch (nalu->nal_unit_type) { case NALU_TYPE_SLICE: case NALU_TYPE_IDR: img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR); img->nal_reference_idc = nalu->nal_reference_idc; img->disposable_flag = (nalu->nal_reference_idc == NALU_PRIORITY_DISPOSABLE); currSlice->dp_mode = PAR_DP_1; currSlice->max_part_nr = 1; currSlice->ei_flag = 0; currStream = currSlice->partArr[0].bitstream; currStream->ei_flag = 0; currStream->frame_bitoffset = currStream->read_len = 0; memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1); currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1); // Some syntax of the Slice Header depends on the parameter set, which depends on // the parameter set ID of the SLice header. Hence, read the pic_parameter_set_id // of the slice header first, then setup the active parameter sets, and then read // the rest of the slice header BitsUsedByHeader = FirstPartOfSliceHeader(); UseParameterSet (currSlice->pic_parameter_set_id); BitsUsedByHeader+= RestOfSliceHeader (); FmoInit (active_pps, active_sps); init_lists(img->type, img->currentSlice->structure); reorder_lists (img->type, img->currentSlice); /* if (img->frame_num==1) // write a reference list { count ++; if (count==1) for (i=0; i<listXsize[0]; i++) write_picture(listX[0][i], p_out2); } */ if (img->MbaffFrameFlag) { init_mbaff_lists(); } if (img->currentSlice->structure!=0) { img->height /=2 ; img->height_cr /=2; } // From here on, active_sps, active_pps and the slice header are valid img->current_mb_nr = currSlice->start_mb_nr; if (img->tr_old != img->ThisPOC) { newframe=1; img->tr_old = img->ThisPOC; } else newframe = 0; if (newframe) current_header = SOP; else current_header = SOS; if(img->structure != img->structure_old) newframe |= 1; img->structure_old = img->structure; //! new stuff StW if(newframe || g_new_frame) { current_header = SOP; g_new_frame=0; } else current_header = SOS; if (active_pps->entropy_coding_mode_flag) { int ByteStartPosition = currStream->frame_bitoffset/8; if (currStream->frame_bitoffset%8 != 0) { ByteStartPosition++; } arideco_start_decoding (&currSlice->partArr[0].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type); } // printf ("read_new_slice: returning %s\n", current_header == SOP?"SOP":"SOS"); FreeNALU(nalu); return current_header; break; case NALU_TYPE_DPA: //! The state machine here should follow the same ideas as the old readSliceRTP() //! basically: //! work on DPA (as above) //! read and process all following SEI/SPS/PPS/PD/Filler NALUs //! if next video NALU is dpB, //! then read and check whether it belongs to DPA, if yes, use it //! else //! ; // nothing //! read and process all following SEI/SPS/PPS/PD/Filler NALUs //! if next video NALU is dpC //! then read and check whether it belongs to DPA (and DPB, if present), if yes, use it, done //! else //! use the DPA (and the DPB if present) /* LC: inserting the code related to DP processing, mainly copying some of the parts related to NALU_TYPE_SLICE, NALU_TYPE_IDR. */ if(expected_slice_type != NALU_TYPE_DPA) { /* oops... we found the next slice, go back! */ fseek(bits, ftell_position, SEEK_SET); FreeNALU(nalu); return current_header; } img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR); img->nal_reference_idc = nalu->nal_reference_idc; img->disposable_flag = (nalu->nal_reference_idc == NALU_PRIORITY_DISPOSABLE); currSlice->dp_mode = PAR_DP_3; currSlice->max_part_nr = 3; currSlice->ei_flag = 0; currStream = currSlice->partArr[0].bitstream; currStream->ei_flag = 0; currStream->frame_bitoffset = currStream->read_len = 0; memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1); currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1); BitsUsedByHeader = FirstPartOfSliceHeader(); UseParameterSet (currSlice->pic_parameter_set_id); BitsUsedByHeader += RestOfSliceHeader (); FmoInit (active_pps, active_sps); init_lists(img->type, img->currentSlice->structure); reorder_lists (img->type, img->currentSlice); if (img->MbaffFrameFlag) { init_mbaff_lists(); } if (img->currentSlice->structure!=0) { img->height /=2 ; img->height_cr /=2; } // From here on, active_sps, active_pps and the slice header are valid img->current_mb_nr = currSlice->start_mb_nr; if (img->tr_old != img->ThisPOC) { newframe=1; img->tr_old = img->ThisPOC; } else newframe = 0; if (newframe) current_header = SOP; else current_header = SOS; if(img->structure != img->structure_old) newframe |= 1; img->structure_old = img->structure; //! new stuff StW if(newframe || g_new_frame) { current_header = SOP; g_new_frame=0; } else current_header = SOS; /* LC: Now I need to read the slice ID, which depends on the value of redundant_pic_cnt_present_flag (pag.49). */ slice_id_a = ue_v("NALU:SLICE_A slice_idr", currStream); if (active_pps->redundant_pic_cnt_present_flag) redundant_pic_cnt_a = ue_v("NALU:SLICE_A redudand_pic_cnt", currStream); else redundant_pic_cnt_a = 0; if (active_pps->entropy_coding_mode_flag) { int ByteStartPosition = currStream->frame_bitoffset/8; if (currStream->frame_bitoffset%8 != 0) { ByteStartPosition++; } arideco_start_decoding (&currSlice->partArr[0].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type); } // printf ("read_new_slice: returning %s\n", current_header == SOP?"SOP":"SOS"); break; case NALU_TYPE_DPB: /* LC: inserting the code related to DP processing */ currStream = currSlice->partArr[1].bitstream; currStream->ei_flag = 0; currStream->frame_bitoffset = currStream->read_len = 0; memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1); currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1); slice_id_b = ue_v("NALU:SLICE_B slice_idr", currStream); if (active_pps->redundant_pic_cnt_present_flag) redundant_pic_cnt_b = ue_v("NALU:SLICE_B redudand_pic_cnt", currStream); else redundant_pic_cnt_b = 0; /* LC: Initializing CABAC for the current data stream. */ if (active_pps->entropy_coding_mode_flag) { int ByteStartPosition = currStream->frame_bitoffset/8; if (currStream->frame_bitoffset % 8 != 0) ByteStartPosition++; arideco_start_decoding (&currSlice->partArr[1].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type); } /* LC: resilience code to be inserted */ /* FreeNALU(nalu); */ /* return current_header; */ break; case NALU_TYPE_DPC: /* LC: inserting the code related to DP processing */ currStream = currSlice->partArr[2].bitstream; currStream->ei_flag = 0; currStream->frame_bitoffset = currStream->read_len = 0; memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1); currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1); slice_id_c = ue_v("NALU:SLICE_C slice_idr", currStream); if (active_pps->redundant_pic_cnt_present_flag) redundant_pic_cnt_c = ue_v("NALU:SLICE_C redudand_pic_cnt", currStream); else redundant_pic_cnt_c = 0; /* LC: Initializing CABAC for the current data stream. */ if (active_pps->entropy_coding_mode_flag) { int ByteStartPosition = currStream->frame_bitoffset/8; if (currStream->frame_bitoffset % 8 != 0) ByteStartPosition++; arideco_start_decoding (&currSlice->partArr[2].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type); } /* LC: resilience code to be inserted */ FreeNALU(nalu); return current_header; break; case NALU_TYPE_SEI: printf ("read_new_slice: Found NALU_TYPE_SEI, len %d\n", nalu->len); InterpretSEIMessage(nalu->buf,nalu->len,img); break; case NALU_TYPE_PPS: ProcessPPS(nalu); break; case NALU_TYPE_SPS: ProcessSPS(nalu); break; case NALU_TYPE_PD: // printf ("read_new_slice: Found 'Access Unit Delimiter' NAL unit, len %d, ignored\n", nalu->len); break; case NALU_TYPE_EOSEQ: // printf ("read_new_slice: Found 'End of Sequence' NAL unit, len %d, ignored\n", nalu->len); break; case NALU_TYPE_EOSTREAM: // printf ("read_new_slice: Found 'End of Stream' NAL unit, len %d, ignored\n", nalu->len); break; case NALU_TYPE_FILL: printf ("read_new_slice: Found NALU_TYPE_FILL, len %d\n", nalu->len); printf ("Skipping these filling bits, proceeding w/ next NALU\n"); break; default: printf ("Found NALU type %d, len %d undefined, ignore NALU, moving on\n", nalu->nal_unit_type, nalu->len); } } FreeNALU(nalu); return current_header; }