www.pudn.com > AVS_M_ver10.rar > Bitstream.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2007 Audio Video Coding Standard, Part ¢ú * * This software module was developed by AVS Audio sub-group * * DISCLAIMER OF WARRANTY * * These software programs are available to the users without any * license fee or royalty on an "as is" basis. The AVS disclaims * any and all warranties, whether express, implied, or statutory, * including any implied warranties of merchantability or of fitness * for a particular purpose. In no event shall the contributors or * the AVS be liable for any incidental, punitive, or consequential * damages of any kind whatsoever arising from the use of this program. * * This disclaimer of warranty extends to the user of this program * and user's customers, employees, agents, transferees, successors, * and assigns. * * The AVS does not represent or warrant that the program furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of AVS, including shareware, may be * subject to royalty fees to patent holders. Information regarding * the AVS patent policy is available from the AVS Web site at * http://www.avs.org.cn * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. ************************************************************************ */ #include#include #include #include "../include/amr_plus.h" extern const UWord8 block_size[]; #define NO_DATA -3 /*-------------------------------------------------------------------------------------* * Funtion WriteHeader() * ~~~~~~~~~~~~~~~~~~ * Write AMR-WB and AMR-WB+ header according to payload selected (see 3gpp ts26.304) * * AMR-WB+ * * Raw File Format (FRTP) * | M.Index (7 bits) | T.F. Index (2 bits) | I.S.F Index (5 bits) | AMR-WB+ bitstream... * * AMR-WB * * | Mono Rate (8 bits) | .........AMR-WB bitstream in IF2 Format (without IF2 Header)... *--------------------------------------------------------------------------------------*/ void WriteHeader(EncoderConfig conf, short length, short offset, FILE * f_serial) { short codec_mode; unsigned char byte; if(conf.extension > 0) { /* write into the bitstream */ byte = (unsigned char) conf.mode_index; fwrite(&byte, sizeof(char), 1, f_serial); /*write mode index information */ byte = (offset<<6); byte += (unsigned char) (conf.fscale_index & 0x1F); fwrite(&byte, sizeof(char), 1, f_serial); } else /* AMR WB */ { codec_mode = conf.mode; if (length == 1) codec_mode = 15; else if (length == 6) codec_mode = 9; byte = (unsigned char) codec_mode; fwrite(&byte, sizeof(char), 1, f_serial); byte = 0; byte = (offset<<6); fwrite(&byte, sizeof(char), 1, f_serial); } } /*-----------------------------------------------------------------* * Funtion WriteBitstreamPlus() * ~~~~~~~~~~~~~~~~~~ * Write AMR-WB+ bitstream *-----------------------------------------------------------------*/ void WriteBitstreamPlus(EncoderConfig conf, short length, short offset, short * serial, FILE * f_serial) { unsigned char byte; short j, k, nb_byte, *pt_serial, *ptr; pt_serial = (short *) serial; nb_byte = ((length / 4) + 7) / 8; ptr = &pt_serial[offset * (length / 4)]; for (j = 0; j < nb_byte; j++) { byte = 0; for (k = 0; k < 8; k++, ptr++) { byte <<= 1; if (*ptr != 0) byte += 1; } fwrite(&byte, sizeof(char), 1, f_serial); } } /*-----------------------------------------------------------------* * Funtion WriteBitstream() * ~~~~~~~~~~~~~~~~~~ * Write AMR-WB bitstream *-----------------------------------------------------------------*/ void WriteBitstream(EncoderConfig conf, short length, short offset, unsigned char * serial, FILE * f_serial) { unsigned char *ptc_serial, *ptc_serial_old; short i; /* Remove IF2 header */ ptc_serial = (unsigned char *) serial + 1; ptc_serial_old = (unsigned char *) serial; for(i = 0; i < length-1; i++) { *ptc_serial_old = (unsigned char)(*ptc_serial) ; ptc_serial++; ptc_serial_old++; } fwrite(serial, sizeof(unsigned char), length - 1, f_serial); } /*-------------------------------------------------------------------------------------* * Funtion ReadHeader() * ~~~~~~~~~~~~~~~~~~ * Read AMR-WB and AMR-WB+ header according to payload selected (see 3gpp ts26.304) * * AMR-WB+ * Raw File Format (FRAW) * | M.Index (7 bits) | T.F. Index (2 bits) | I.S.F Index (5 bits) | AMR-WB+ bitstream... * * AMR-WB * * | Mono Rate (8 bits) | .........AMR-WB bitstream in IF2 Format (without IF2 Header)... *--------------------------------------------------------------------------------------*/ short ReadHeader(short *tfi, int *bfi, short FileFormat, short *extension, short *mode, short *st_mode, short *fst, short offset, FILE *f_serial) { short mode_index, fst_index, index, nb_read = 0; unsigned char byte; nb_read += fread(&byte, sizeof(unsigned char), 1, f_serial); if(nb_read ==0) return nb_read; mode_index = (byte & 127); /* If frame ereased : don't change old conf just modify mode */ if( mode_index > 47 || mode_index < 0 || /* mode unknown */ mode_index == 14 || mode_index == 15 || /* Frame lost or ereased */ (mode_index == 9 && *extension == 1)) /* WB SID in WB+ frame not supported case so declare a NO_DATA*/ { nb_read += fread(&byte, sizeof(unsigned char), 1, f_serial); /* read one more byte to ensure empty header */ *tfi = (byte & 0xc0)>>6; /* tfi extrapolated by RTP packetizer */ fst_index = (byte & 0x1F); *fst = isfIndex[fst_index]; if(mode_index == 14) /* frame lost WB or WB+*/ { bfi[*tfi] = 1; } else if (mode_index == 15) { bfi[*tfi] = 0; /* DTX in WB reset BFI vector */ } *mode = mode_index; return NO_DATA; /* There is no more data to read */ } *st_mode = -1; if(mode_index >15) /* wb+ */ { if(mode_index < 24) /* Mono mode only */ { *mode = mode_index - 16; } else { index = mode_index - 24; *mode = miMode[2*index]; *st_mode = miMode[2*index+1]; } *extension = 1; nb_read += fread(&byte, sizeof(unsigned char), 1, f_serial); *tfi = (byte & 0xc0)>>6; fst_index = (byte & 0x1F); if(fst_index < 1) fst_index = 1; /* prevent isf < 0.5 */ *fst = isfIndex[fst_index]; } else /* WB and caracterize WB+*/ { if(mode_index == 10) { *extension = 1; *mode = 2; /* 14m */ } else if (mode_index == 11) { *extension = 1; *mode = 2; /* 18s */ *st_mode = 6; } else if (mode_index == 12) { *extension = 1; *mode = 7; /* 24m */ } else if (mode_index == 13) { *extension = 1; *mode = 5; /* 24s */ *st_mode = 7; } else { *extension = 0; *mode = mode_index; } nb_read += fread(&byte, sizeof(unsigned char), 1, f_serial); *tfi = (byte & 0xc0)>>6; fst_index = (byte & 0x1F); if(fst_index != 0 && fst_index != 8) { fprintf( stderr, "Internal Sampling Frequency not supported with AMW WB and caracterized WB+ modes " ); exit(EXIT_FAILURE); } *fst = isfIndex[fst_index]; } bfi[*tfi] = 0; /* Good frame */ return nb_read; } /*-----------------------------------------------------------------* * Funtion WriteBitstreamPlus() * ~~~~~~~~~~~~~~~~~~ * Write AMR-WB+ bitstream *-----------------------------------------------------------------*/ static short ReadBitstreamPlus(short nb_bits, short nb_byte, short *serial, FILE * f_serial, short offset) { unsigned char byte; short j, k, n, *ptr; ptr = &serial[offset * (nb_bits / 4)]; n = 0; for (j = 0; j < nb_byte; j++) { n += fread(&byte, sizeof(unsigned char), 1, f_serial); for (k = 0; k < 8; k++, ptr++) { *ptr = (byte & (short) 128) == (short) 128; byte <<= 1; } } return n; } /*-----------------------------------------------------------------* * Funtion WriteBitstream() * ~~~~~~~~~~~~~~~~~~ * Write AMR-WB bitstream + creation of IF2 Header *-----------------------------------------------------------------*/ static short ReadBitstream(short nb_byte, unsigned char *serialAmrwb, short mode, FILE * f_serial) { unsigned char *ptc_serial, ctemp; unsigned char *ptc_serial_new; short n, i; /* update mode changes */ n = fread(serialAmrwb, sizeof(unsigned char), nb_byte - 1, f_serial); ptc_serial = serialAmrwb + nb_byte - 2; ptc_serial_new = serialAmrwb + nb_byte - 1; for(i = 0; i < nb_byte - 1; i++) { *ptc_serial_new = *ptc_serial; ptc_serial--; ptc_serial_new--; } /* add IF2 Header */ ctemp = (unsigned char)(1<<2); /* Add FQI */ ctemp += (unsigned char)(mode <<3); /* Add Frame Type */ *ptc_serial_new = ctemp; return n; } short ReadRawFile(short *tfi, int *bfi, DecoderConfig *conf, short *extension, short *mode, short *st_mode, short *fst, FILE *f_serial, void * serial) { short i, n = 0, nb_bits, nb_byte, *pt_serial, *ptr; pt_serial = (short *) serial; for (i = 0; i < 4; i++) { n = ReadHeader(tfi, bfi, conf->FileFormat, extension, mode, st_mode, fst, i, f_serial); if(!n) break; /* assume there is no amrwb -> wb+ switching inside superframe */ if (n != NO_DATA) { /* update mode and st_mode only if mode_index != (14 ||15) */ conf->mode = *mode; conf->st_mode = *st_mode; if(*extension >0) { nb_bits = get_nb_bits(*extension, *mode, *st_mode); ptr = &pt_serial[i * (nb_bits / 4)]; nb_byte = ((nb_bits / 4) + 7 ) / 8; n = ReadBitstreamPlus(nb_bits, nb_byte, pt_serial, f_serial, i); if (n != nb_byte) break; } else { nb_byte = block_size[*mode]; n = ReadBitstream(nb_byte, (unsigned char*) serial, *mode, f_serial); break; } } else if (*extension == 0) { if (*mode == 15) { /* DTX FRAME (NO DATA)*/ ((unsigned char*)serial)[0] = 0x7C; /* need in AMR WB */ } else if (*mode == 14) /* Frame lost */ ((unsigned char*)serial)[0] = 0x74; /* need in AMR WB */ break; } } return n; }