📄 mpegdec.c
字号:
* scale_percent = scale factor in % to apply to the decoded * output 100 is the nominal value * Return 0 if Ok, MPEGDEC_ERR_BADVALUE if invalid scale */int MPEGDEC_scale(MPEGDEC_STREAM *mpds, INT32 scale_percent){ MPA_STREAM *mps; mps = (MPA_STREAM *) mpds->handle; if (MPEGSUB_scale(mps->mpegsub, scale_percent)) return(MPEGDEC_ERR_BADVALUE); return(MPEGDEC_ERR_NONE);}/****************************************************************************//* * Decode the current MPEG Audio frame * Input: mpds = mpeg audio stream ptr returned by MPEGDEC_open * Output: pcm[] = 16-bit samples * pcm[0] is mono or left voice or channel 1 * pcm[1] is right or channel 2 * Return the number of samples * * Note: pcm[]'s be at least arrays of MPEGDEC_PCM_SIZE * number of samples can be 0 if current frame is skipped, in case * of error in crc or not enough data for decoding (layer III) * number of samples = 0 does not indicate end of stream !*/INT32 MPEGDEC_decode_frame(MPEGDEC_STREAM *mpds, INT16 *pcm[MPEGDEC_MAX_CHANNELS]){ MPA_STREAM *mps; INT32 count; int err; mps = (MPA_STREAM *) mpds->handle; mps->pcm[0] = pcm[0]; mps->pcm[1] = pcm[1]; if (mps->need_sync) { // #10 err = synchronize(mps); if (err) return(err); mps->need_sync = FALSE; } else { // FALSE: don't fail if MPEG Audio sync not at first err = MPEGDEC_read_header(mps, FALSE); if (err) return(err); } switch (mps->header.layer) { case 1: count = MPEG1_decode_frame(mps); break; case 2: count = MPEG2_decode_frame(mps); break; case 3: count = MPEG3_decode_frame(mps); break; default: count = 0; } mps->frame++; return(count);}/****************************************************************************//* * Reset the decoder * Inputs: mpds = mpeg audio stream ptr returned by MPEGDEC_open */static int decoder_reset(MPEGDEC_STREAM *mpds){ int err; MPA_STREAM *mps; if (!mpds) return(MPEGDEC_ERR_EOF); mps = (MPA_STREAM *) mpds->handle; // Reset all layer's decoders err = MPEG1_reset(mps); if (err) return(err); err = MPEG2_reset(mps); if (err) return(err); err = MPEG3_reset(mps); if (err) return(err); // Reset subband buffers & offsets err = MPEGSUB_reset(mps->mpegsub); if (err) return(err); err = MPEGIMDCT_reset(mps->mpegimdct); return(err);}/****************************************************************************//* * Seek into an MPEG Audio stream * Inputs: mpds = mpeg audio stream ptr returned by MPEGDEC_open * ms_time_position = absolute time position in ms */int MPEGDEC_seek(MPEGDEC_STREAM *mpds, UINT32 ms_time_position){ int err = -1; MPA_STREAM *mps; if (!mpds) return(MPEGDEC_ERR_EOF); mps = (MPA_STREAM *) mpds->handle; if (mps) { BITSTREAM *bs = mps->bitstream; REAL exact_seek; REAL slots; INT32 seek_pos; INT32 frame_bytes; INT32 frame; exact_seek = ((REAL) mps->bitrate * (REAL) ms_time_position) * 0.125; // Calculate nearest # of frames if (mps->header.layer == 1) frame_bytes = 48000; // 384/8*1000 else if ((mps->header.layer == 3) && (mps->header.ID == MPA_ID_2)) frame_bytes = 72000; else frame_bytes = 144000; slots = (REAL) (frame_bytes * mps->bitrate) / (REAL) mps->sfreq; frame = (INT32) (exact_seek / slots); // Calcultate seek pos in multiple of frames seek_pos = (INT32) ((REAL) frame * slots); // Here sub 1 to be sure to get header seek_pos--; if (seek_pos < 0) seek_pos = 0; seek_pos += mps->bitstream_start_pos; err = BSTR_seek(bs, seek_pos); if (!err) { mps->frame = frame; decoder_reset(mpds); mps->need_sync = TRUE; } } return(err);}/****************************************************************************//* * Get the current time position of an MPEG Audio stream * Input: mpds = mpeg audio stream ptr returned by MPEGDEC_open * Output: ms_time_position = absolute time position in ms * Return 0 if Ok */int MPEGDEC_time(MPEGDEC_STREAM *mpds, UINT32 *ms_time_position){ int err = -1; MPA_STREAM *mps; if (!mpds) return(MPEGDEC_ERR_EOF); mps = (MPA_STREAM *) mpds->handle; if (mps) { INT32 frame_bits; if (mps->header.layer == 1) frame_bits = 384000; // 384*1000 else if ((mps->header.layer == 3) && (mps->header.ID == MPA_ID_2)) frame_bits = 576000; else frame_bits = 1152000; *ms_time_position = (UINT32) (((REAL) mps->frame * (REAL) frame_bits) / (REAL) mps->sfreq); err = 0; } return(err);}/****************************************************************************//* * Close an MPEG Audio stream * Input: mpds = mpeg audio stream ptr returned by MPEGDEC_open */void MPEGDEC_close(MPEGDEC_STREAM *mpds){ MPA_STREAM *mps; if (!mpds) return; mps = (MPA_STREAM *) mpds->handle; if (mps) { if (mps->mpegimdct) MPEGIMDCT_close(mps->mpegimdct); if (mps->mpegsub) MPEGSUB_close(mps->mpegsub); if (mps->huffman) HUFF_close(mps->huffman); if (mps->bitstream) BSTR_close(mps->bitstream); free(mps); } free(mpds);}/****************************************************************************//* * Open an MPEG Audio stream * Inputs: filename = stream filename to decode * ctrl = decoding controls * Return the mpeg audio stream ptr or NULL if failed to open stream */MPEGDEC_STREAM *MPEGDEC_open(char *filename, MPEGDEC_CTRL *ctrl){ MPEGDEC_STREAM *mpds; MPA_STREAM *mps; INT16 freq_div; INT16 quality; INT32 freq_max; INT32 buffer_size; MPEGDEC_LAYER *dec_lay; MPEGDEC_OUTPUT *dec_out; mpds = (MPEGDEC_STREAM *) malloc(sizeof(MPEGDEC_STREAM)); if (!mpds) return(NULL); memset(mpds, 0, sizeof(MPEGDEC_STREAM)); mps = (MPA_STREAM *) malloc(sizeof(MPA_STREAM)); if (!mps) { MPEGDEC_close(mpds); return(NULL); } memset(mps, 0, sizeof(MPA_STREAM)); mpds->handle = mps; // Multiple of 4 bytes buffer_size = ctrl->stream_buffer_size & (INT32) (~3); if (buffer_size <= 0) buffer_size = MPEGDEC_BITSTREAM_BUFFER_SIZE; mps->bitstream = BSTR_open((BITSTREAM_ACCESS *) ctrl->bs_access, filename, buffer_size); if (!mps->bitstream) { MPEGDEC_close(mpds); return(NULL); } mps->stream_size = mps->bitstream->bitstream_size; mps->huffman = HUFF_open(); if (!mps->huffman) { MPEGDEC_close(mpds); return(NULL); } mps->current_table = -1;#if 1 if (synchronize(mps)) { (void) MPEGDEC_close(mpds); return(NULL); } mps->need_sync = FALSE; mps->bitstream_start_pos = mps->header.header_pos; mps->stream_size = mps->bitstream->bitstream_size - mps->bitstream_start_pos;#else if (MPEGDEC_read_header(mps, (BOOL) ctrl->check_mpeg)) { MPEGDEC_close(mpds); return(NULL); }#endif if (mps->header.layer < 3) dec_lay = &ctrl->layer_1_2; else dec_lay = &ctrl->layer_3; mps->force_mono = dec_lay->force_mono; if (mps->stereo) dec_out = &dec_lay->stereo; else dec_out = &dec_lay->mono; freq_div = dec_out->freq_div; quality = dec_out->quality; freq_max = dec_out->freq_max; if (freq_div == 0) { INT32 freq = mps->sfreq; mps->freq_div = 1; do { if (freq <= freq_max) break; mps->freq_div <<= 1; freq >>= 1; } while (mps->freq_div < 4); } else { mps->freq_div = freq_div; } switch (mps->freq_div) { case 2: mps->sb_max = MPA_SBLIMIT / 2; break; case 4: mps->sb_max = MPA_SBLIMIT / 4; break; default: mps->freq_div = 1; mps->sb_max = MPA_SBLIMIT; break; } mps->quality = quality; if (mps->quality < MPEGDEC_QUALITY_LOW) mps->quality = MPEGDEC_QUALITY_LOW; else if (mps->quality > MPEGDEC_QUALITY_HIGH) mps->quality = MPEGDEC_QUALITY_HIGH; mps->mpegsub = MPEGSUB_open(mps->freq_div, mps->quality); if (!mps->mpegsub) { MPEGDEC_close(mpds); return(NULL); } mps->mpegimdct = MPEGIMDCT_open(); if (!mps->mpegimdct) { MPEGDEC_close(mpds); return(NULL); } fill_info(mpds); BSTR_seek(mps->bitstream, mps->bitstream_start_pos); decoder_reset(mpds); return(mpds);}/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -