static void Sequence( mpeg_decode* dec ) { int i; loadbits(dec); dec->width = getbits(dec,12); dec->height = getbits(dec,12); loadbits(dec); dec->aspect = getbits(dec,4); dec->Codec.In.Format.PacketRate.Den = 1001; dec->Codec.In.Format.PacketRate.Num = FrameRate[getbits(dec,4)]; dec->Codec.FrameTime = Scale(TICKSPERSEC,dec->Codec.In.Format.PacketRate.Den,dec->Codec.In.Format.PacketRate.Num); loadbits(dec); dec->Codec.In.Format.ByteRate = getbits(dec,18) * 50; if (dec->Codec.In.Format.ByteRate > 8*1024*1024) dec->Codec.In.Format.ByteRate = 0; flushbits(dec,1); // marker flushbits(dec,10); // vbv_buffer_size flushbits(dec,1); loadbits(dec); if (getbits1(dec)) { for (i=0;i<64;i++) { loadbits(dec); dec->IntraMatrix[i] = (uint8_t)getbits(dec,8); } } else { for (i=0;i<64;i++) dec->IntraMatrix[i] = MPEG1_IntraMatrix[dec->zigzag[i]]; } if (getbits1(dec)) { for (i=0;i<64;i++) { loadbits(dec); dec->InterMatrix[i] = (uint8_t)getbits(dec, 8); } } else { for (i=0;i<64;i++) dec->InterMatrix[i] = 16; } dec->ValidSeq = 1; }
int getTMNMV () { int code; if (trace) fprintf (trace_file, "motion_code ("); if (getbits1 ()) { if (trace) fprintf (trace_file, "1): 0\n"); return 0; } if ((code = showbits (12)) >= 512) { code = (code >> 8) - 2; flushbits (TMNMVtab0[code].len); if (trace) { fprintf (trace_file, "0"); printbits (code + 2, 4, TMNMVtab0[code].len); fprintf (trace_file, "): %d\n", TMNMVtab0[code].val); } return TMNMVtab0[code].val; }
int getslicehdr() { int slice_vertical_position_extension, intra_slice; int qs; slice_vertical_position_extension = (ld->mpeg2 && vertical_size>2800) ? getbits(3) : 0; qs = getbits(5); ld->quant_scale = ld->mpeg2 ? (ld->qscale_type ? non_linear_mquant_table[qs] : qs<<1) : qs; if (getbits(1)) { intra_slice = getbits(1); flushbits(7); ext_bit_info(); } else intra_slice = 0; if (verbose>2) { if (verbose>3) { if (ld->mpeg2 && vertical_size>2800) printf(" slice_vertical_position_extension=%d\n",slice_vertical_position_extension); printf(" quantizer_scale_code=%d\n",qs); } } return slice_vertical_position_extension; }
static void getgophdr() { int drop_flag, hour, minute, sec, frame, closed_gop, broken_link; drop_flag = getbits(1); hour = getbits(5); minute = getbits(6); flushbits(1); sec = getbits(6); frame = getbits(6); closed_gop = getbits(1); broken_link = getbits(1); if (verbose>0) { if (verbose>1) { printf(" drop_flag=%d\n",drop_flag); printf(" timecode %d:%02d:%02d:%02d\n",hour,minute,sec,frame); printf(" closed_gop=%d\n",closed_gop); printf(" broken_link=%d\n",broken_link); } } ext_user_data(); }
// max 11bits static INLINE int getDCdiff(int dct_dc_size, mpeg_decode* dec) { int code = showbits(dec,32); //we need only dct_dc_size bits (but in the higher bits) int adj = 0; flushbits(dec,dct_dc_size); if (code >= 0) adj = (-1 << dct_dc_size) + 1; return adj + ((uint32_t)code >> (32-dct_dc_size)); }
// max 10 bits static INLINE int getDCsizeChr( mpeg_decode* dec ) { int i,code; if (!getbits1(dec)) return getbits(dec,1); code = showbits(dec,9); for (i=1;i<10;i++,code<<=1) if (!(code & 256)) { flushbits(dec,i); return i+1; } flushbits(dec,9); return 11; }
// max 9 bits static INLINE int getDCsizeLum( mpeg_decode* dec ) { int i,code; if (!getbits1(dec)) return getbits(dec,1)+1; if (!getbits1(dec)) return getbits(dec,1)*3; code = showbits(dec,7); for (i=1;i<8;i++,code<<=1) if (!(code & 64)) { flushbits(dec,i); return i+3; } flushbits(dec,7); return 11; }
static void Picture( mpeg_decode* dec ) { static const int16_t aspect[16] = { 0,10000, 6735, 7031, 7615, 8055, 8437, 8935, 9157, 9815,10255,10695, 10950,11575,12015, 0, }; if (!dec->Codec.In.Format.Format.Video.Aspect && aspect[dec->aspect]) dec->Codec.In.Format.Format.Video.Aspect = Scale(ASPECT_ONE,10000,aspect[dec->aspect]); CodecIDCTSetFormat(&dec->Codec,PF_YUV420,dec->width,dec->height,dec->width,dec->height,dec->Codec.In.Format.Format.Video.Aspect); flushbits(dec,10); // temporal ref loadbits(dec); dec->prediction_type = getbits(dec,3); flushbits(dec,16); // non constant bit rate loadbits(dec); if (dec->prediction_type == P_VOP || dec->prediction_type == B_VOP) { dec->full_pixel[0] = getbits(dec,1); dec->fcode[0] = getbits(dec,3)-1; } if (dec->prediction_type == B_VOP) { dec->full_pixel[1] = getbits(dec,1); dec->fcode[1] = getbits(dec,3)-1; } dec->frame_state = 1; DEBUG_MSG1(DEBUG_VCODEC,T("MPEG Picture:%d"),dec->prediction_type); }
static void sequence_extension() { int prof_lev; int horizontal_size_extension, vertical_size_extension; int bit_rate_extension, vbv_buffer_size_extension, low_delay; int frame_rate_extension_n, frame_rate_extension_d; ld->mpeg2 = 1; ld->scalable_mode = SC_NONE; /* unless overwritten by seq. scal. ext. */ prof_lev = getbits(8); prog_seq = getbits(1); chroma_format = getbits(2); horizontal_size_extension = getbits(2); vertical_size_extension = getbits(2); bit_rate_extension = getbits(12); flushbits(1); vbv_buffer_size_extension = getbits(8); low_delay = getbits(1); frame_rate_extension_n = getbits(2); frame_rate_extension_d = getbits(5); horizontal_size = (horizontal_size_extension<<12) | (horizontal_size&0x0fff); vertical_size = (vertical_size_extension<<12) | (vertical_size&0x0fff); if (verbose>0) { if (verbose>1) { printf(" profile_and_level_indication=%d\n",prof_lev); if (prof_lev<128) { printf(" profile=%d, level=%d\n",prof_lev>>4,prof_lev&15); } printf(" progressive_sequence=%d\n",prog_seq); printf(" chroma_format=%d\n",chroma_format); printf(" horizontal_size_extension=%d\n",horizontal_size_extension); printf(" vertical_size_extension=%d\n",vertical_size_extension); printf(" bit_rate_extension=%d\n",bit_rate_extension); printf(" vbv_buffer_size_extension=%d\n",vbv_buffer_size_extension); printf(" low_delay=%d\n",low_delay); printf(" frame_rate_extension_n=%d\n",frame_rate_extension_n); printf(" frame_rate_extension_d=%d\n",frame_rate_extension_d); }
void startcode () { /* search for new picture start code */ while (showbits (PSC_LENGTH) != 1l) flushbits (1); }
int gethdr_h263( mp4_decode *dec ) { int code; bytealign(dec); loadbits(dec); code = getbits(dec,22-8); while (!eofbits(dec)) { loadbits(dec); code = ((code << 8) + getbits(dec,8)) & 0x3FFFFF; if (code == 32) break; } if (code != 32) return 0; flushbits(dec,8); // picture timestamp loadbits(dec); if (!getbits1(dec)) // marker return 0; if (getbits1(dec)) // h263 id return 0; flushbits(dec,3); code = getbits(dec,3); // format if (code == 6 || code == 7) { if (dec->showerror) { dec->showerror = 0; ShowError(dec->Codec.Node.Class,MPEG4_ID,MPEG4_ERROR_H263); } //todo: finish return 0; } else { static const int size[8][2] = { { 0,0 }, { 128,96 }, { 176,144 }, { 352,288 }, { 704,576 }, { 1408,1152 }}; int width = size[code][0]; int height = size[code][1]; if (!dec->ignoresize && (!width || CodecIDCTSetFormat(&dec->Codec,PF_YUV420, dec->Codec.In.Format.Video.Width,dec->Codec.In.Format.Video.Height,width,height) != ERR_NONE)) { dec->validvol = 0; return 0; } loadbits(dec); dec->prediction_type = getbits(dec,1); dec->long_vectors = (char)getbits(dec,1); if (getbits1(dec)) // sac not supported return 0; getbits(dec,1); // obmc if (getbits1(dec)) // pb frame not supported return 0; dec->quantizer = getbits(dec,5); flushbits(dec,1); dec->rounding = 0; } while (getbits1(dec)) // pei { flushbits(dec,8); loadbits(dec); } dec->fcode_for = 1; dec->validvol = 1; dec->Codec.IDCT.Ptr->Set(dec->Codec.IDCT.Ptr,IDCT_ROUNDING,&dec->rounding,sizeof(bool_t)); return 1; }
// write a Differential Data Stream void writeDDSfile(const char *filename,unsigned char *data,size_t bytes,unsigned int skip,unsigned int strip,int nofree) { int version=1; unsigned char *ptr1,*ptr2; int pre1,pre2, act1,act2, tmp1,tmp2; unsigned int cnt,cnt1,cnt2; int bits,bits1,bits2; if (bytes<1) ERRORMSG(); if (bytes>DDS_INTERLEAVE) version=2; if (skip<1 || skip>4) skip=1; if (strip<1 || strip>65536) strip=1; if ((DDS_file=fopen(filename,"wb"))==NULL) ERRORMSG(); fprintf(DDS_file,"%s",(version==1)?DDS_ID:DDS_ID2); deinterleave(data,bytes,skip,DDS_INTERLEAVE); initbuffer(); writebits(DDS_file,skip-1,2); writebits(DDS_file,strip++-1,16); ptr1=ptr2=data; pre1=pre2=0; cnt=cnt1=cnt2=0; bits=bits1=bits2=0; while (cnt++<bytes) { tmp1=*ptr1++; if (cnt<=strip) act1=tmp1-pre1; else act1=tmp1-pre1-*(ptr1-strip)+*(ptr1-strip-1); pre1=tmp1; while (act1<-128) act1+=256; while (act1>127) act1-=256; if (act1<=0) for (bits=0; (1<<bits)/2<-act1; bits++) ; else for (bits=0; (1<<bits)/2<=act1; bits++) ; bits=DDS_decode(DDS_code(bits)); if (cnt1==0) { cnt1++; bits1=bits; continue; } if (cnt1<(1<<DDS_RL)-1 && bits==bits1) { cnt1++; continue; } if (cnt1+cnt2<(1<<DDS_RL) && (cnt1+cnt2)*max(bits1,bits2)<cnt1*bits1+cnt2*bits2+DDS_RL+3) { cnt2+=cnt1; if (bits1>bits2) bits2=bits1; } else { writebits(DDS_file,cnt2,DDS_RL); writebits(DDS_file,DDS_code(bits2),3); while (cnt2-->0) { tmp2=*ptr2++; if (ptr2-strip<=data) act2=tmp2-pre2; else act2=tmp2-pre2-*(ptr2-strip)+*(ptr2-strip-1); pre2=tmp2; while (act2<-128) act2+=256; while (act2>127) act2-=256; writebits(DDS_file,act2+(1<<bits2)/2,bits2); } cnt2=cnt1; bits2=bits1; } cnt1=1; bits1=bits; } if (cnt1+cnt2<(1<<DDS_RL) && (cnt1+cnt2)*max(bits1,bits2)<cnt1*bits1+cnt2*bits2+DDS_RL+3) { cnt2+=cnt1; if (bits1>bits2) bits2=bits1; } else { writebits(DDS_file,cnt2,DDS_RL); writebits(DDS_file,DDS_code(bits2),3); while (cnt2-->0) { tmp2=*ptr2++; if (ptr2-strip<=data) act2=tmp2-pre2; else act2=tmp2-pre2-*(ptr2-strip)+*(ptr2-strip-1); pre2=tmp2; while (act2<-128) act2+=256; while (act2>127) act2-=256; writebits(DDS_file,act2+(1<<bits2)/2,bits2); } cnt2=cnt1; bits2=bits1; } if (cnt2!=0) { writebits(DDS_file,cnt2,DDS_RL); writebits(DDS_file,DDS_code(bits2),3); while (cnt2-->0) { tmp2=*ptr2++; if (ptr2-strip<=data) act2=tmp2-pre2; else act2=tmp2-pre2-*(ptr2-strip)+*(ptr2-strip-1); pre2=tmp2; while (act2<-128) act2+=256; while (act2>127) act2-=256; writebits(DDS_file,act2+(1<<bits2)/2,bits2); } } flushbits(DDS_file); fclose(DDS_file); if (nofree==0) free(data); else interleave(data,bytes,skip,DDS_INTERLEAVE); }
static void getseqhdr() { int i; int aspect_ratio, picture_rate, vbv_buffer_size; int constrained_parameters_flag; int load_intra_quantizer_matrix, load_non_intra_quantizer_matrix; int bit_rate; horizontal_size = getbits(12); vertical_size = getbits(12); aspect_ratio = getbits(4); picture_rate = getbits(4); bit_rate = getbits(18); flushbits(1); /* marker bit (=1) */ vbv_buffer_size = getbits(10); constrained_parameters_flag = getbits(1); if (load_intra_quantizer_matrix = getbits(1)) { for (i=0; i<64; i++) ld->intra_quantizer_matrix[zig_zag_scan[i]] = getbits(8); } else { for (i=0; i<64; i++) ld->intra_quantizer_matrix[i] = default_intra_quantizer_matrix[i]; } if (load_non_intra_quantizer_matrix = getbits(1)) { for (i=0; i<64; i++) ld->non_intra_quantizer_matrix[zig_zag_scan[i]] = getbits(8); } else { for (i=0; i<64; i++) ld->non_intra_quantizer_matrix[i] = 16; } /* copy luminance to chrominance matrices */ for (i=0; i<64; i++) { ld->chroma_intra_quantizer_matrix[i] = ld->intra_quantizer_matrix[i]; ld->chroma_non_intra_quantizer_matrix[i] = ld->non_intra_quantizer_matrix[i]; } if (verbose>0) { if (verbose>1) { printf(" horizontal_size=%d\n",horizontal_size); printf(" vertical_size=%d\n",vertical_size); printf(" aspect_ratio=%d\n",aspect_ratio); printf(" picture_rate=%d\n",picture_rate); printf(" bit_rate=%d\n",bit_rate); printf(" vbv_buffer_size=%d\n",vbv_buffer_size); printf(" constrained_parameters_flag=%d\n",constrained_parameters_flag); printf(" load_intra_quantizer_matrix=%d\n",load_intra_quantizer_matrix); printf(" load_non_intra_quantizer_matrix=%d\n",load_non_intra_quantizer_matrix); } } ext_user_data(); }
inline void startcode(void) { bitpos=(bitpos+7)&~7; while (showbits(24)!=1) flushbits(8); }
void thread_work_dist() { int tmp, tmp1; int rc, t, status; int excess, chunk; #if (NUM_THREADS>1) pthread_attr_t attr; pthread_t thread[NUM_THREADS-1]; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); #endif chunk = height2/NUM_THREADS; excess = (height2/16)%NUM_THREADS; for(t=0;t < NUM_THREADS;t++) { if (t==0) { thread_data_array[t].s_height = 0; thread_data_array[t].s_mbh = 0; thread_data_array[t].pp_smbh = 0; tmp = chunk; } else { thread_data_array[t].s_height = thread_data_array[t-1].e_height; thread_data_array[t].s_mbh = thread_data_array[t-1].e_mbh; thread_data_array[t].pp_smbh = thread_data_array[t-1].pp_embh; tmp = thread_data_array[t-1].e_height + chunk; } if (excess) { tmp = tmp + 16 - (tmp%16); excess--; } else { tmp = tmp - (tmp%16); } tmp1 = tmp/16; thread_data_array[t].e_height = tmp; thread_data_array[t].pp_embh = tmp1; thread_data_array[t].e_mbh = tmp1*mb_width; thread_data_array[t].id = t; thread_data_array[t].data_ptr = &data_args; #if (NUM_THREADS>1) /* create threads */ if (t<NUM_THREADS-1) { rc = pthread_create(&thread[t], &attr, thread_work, (void*) &thread_data_array[t]); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } #endif } #if (NUM_THREADS>1) /* Free attribute and wait for the other threads */ pthread_attr_destroy(&attr); #endif /* disabled rate control, detail can be found at putpic.c */ putpicthdr(); if (!mpeg1) putpictcodext(); alignbits(); /*align common bitstream buffer */ thread_work(&thread_data_array[NUM_THREADS-1]); #if (NUM_THREADS>1) for(t=0;t < NUM_THREADS-1;t++) { rc = pthread_join(thread[t], (void **)&status); if (rc) { printf("ERROR; return code from pthread_join() is %d\n", rc); exit(-1); } flushbits(t); } #endif flushbits(NUM_THREADS-1); }