📄 pcm.c
字号:
v = *samples++; v += 0x8000; bytestream_put_be16(&dst, v); } break; case CODEC_ID_PCM_S8: for(;n>0;n--) { v = *samples++; *dst++ = v >> 8; } break; case CODEC_ID_PCM_U8: for(;n>0;n--) { v = *samples++; *dst++ = (v >> 8) + 128; } break; case CODEC_ID_PCM_ZORK: for(;n>0;n--) { v= *samples++ >> 8; if(v<0) v = -v; else v+= 128; *dst++ = v; } break; case CODEC_ID_PCM_ALAW: for(;n>0;n--) { v = *samples++; *dst++ = linear_to_alaw[(v + 32768) >> 2]; } break; case CODEC_ID_PCM_MULAW: for(;n>0;n--) { v = *samples++; *dst++ = linear_to_ulaw[(v + 32768) >> 2]; } break; default: return -1; } //avctx->frame_size = (dst - frame) / (sample_size * avctx->channels); return dst - frame;}typedef struct PCMDecode { short table[256];} PCMDecode;static int pcm_decode_init(AVCodecContext * avctx){ PCMDecode *s = avctx->priv_data; int i; switch(avctx->codec->id) { case CODEC_ID_PCM_ALAW: for(i=0;i<256;i++) s->table[i] = alaw2linear(i); break; case CODEC_ID_PCM_MULAW: for(i=0;i<256;i++) s->table[i] = ulaw2linear(i); break; default: break; } return 0;}/** * \brief convert samples to 16 bit * \param bps byte per sample for the source format, must be >= 2 * \param le 0 for big-, 1 for little-endian * \param us 0 for signed, 1 for unsigned input * \param src input samples * \param samples output samples * \param src_len number of bytes in src */static inline void decode_to16(int bps, int le, int us, const uint8_t **src, short **samples, int src_len){ int usum = us ? -0x8000 : 0; register int n = src_len / bps; if (le) *src += bps - 2; for(;n>0;n--) { register int v; if (le) v = AV_RL16(*src); else v = AV_RB16(*src); v += usum; *(*samples)++ = v; *src += bps; } if (le) *src -= bps - 2;}static int pcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size){ PCMDecode *s = avctx->priv_data; int c, n; short *samples; const uint8_t *src, *src2[MAX_CHANNELS]; samples = data; src = buf; n= av_get_bits_per_sample(avctx->codec_id)/8; if(n && buf_size % n){ av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\n"); return -1; } if(avctx->channels <= 0 || avctx->channels > MAX_CHANNELS){ av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n"); return -1; } buf_size= FFMIN(buf_size, *data_size/2); *data_size=0; n = buf_size/avctx->channels; for(c=0;c<avctx->channels;c++) src2[c] = &src[c*n]; switch(avctx->codec->id) { case CODEC_ID_PCM_S32LE: decode_to16(4, 1, 0, &src, &samples, buf_size); break; case CODEC_ID_PCM_S32BE: decode_to16(4, 0, 0, &src, &samples, buf_size); break; case CODEC_ID_PCM_U32LE: decode_to16(4, 1, 1, &src, &samples, buf_size); break; case CODEC_ID_PCM_U32BE: decode_to16(4, 0, 1, &src, &samples, buf_size); break; case CODEC_ID_PCM_S24LE: decode_to16(3, 1, 0, &src, &samples, buf_size); break; case CODEC_ID_PCM_S24BE: decode_to16(3, 0, 0, &src, &samples, buf_size); break; case CODEC_ID_PCM_U24LE: decode_to16(3, 1, 1, &src, &samples, buf_size); break; case CODEC_ID_PCM_U24BE: decode_to16(3, 0, 1, &src, &samples, buf_size); break; case CODEC_ID_PCM_S24DAUD: n = buf_size / 3; for(;n>0;n--) { uint32_t v = bytestream_get_be24(&src); v >>= 4; // sync flags are here *samples++ = ff_reverse[(v >> 8) & 0xff] + (ff_reverse[v & 0xff] << 8); } break; case CODEC_ID_PCM_S16LE: n = buf_size >> 1; for(;n>0;n--) { *samples++ = bytestream_get_le16(&src); } break; case CODEC_ID_PCM_S16LE_PLANAR: for(n>>=1;n>0;n--) for(c=0;c<avctx->channels;c++) *samples++ = bytestream_get_le16(&src2[c]); src = src2[avctx->channels-1]; break; case CODEC_ID_PCM_S16BE: n = buf_size >> 1; for(;n>0;n--) { *samples++ = bytestream_get_be16(&src); } break; case CODEC_ID_PCM_U16LE: n = buf_size >> 1; for(;n>0;n--) { *samples++ = bytestream_get_le16(&src) - 0x8000; } break; case CODEC_ID_PCM_U16BE: n = buf_size >> 1; for(;n>0;n--) { *samples++ = bytestream_get_be16(&src) - 0x8000; } break; case CODEC_ID_PCM_S8: n = buf_size; for(;n>0;n--) { *samples++ = *src++ << 8; } break; case CODEC_ID_PCM_U8: n = buf_size; for(;n>0;n--) { *samples++ = ((int)*src++ - 128) << 8; } break; case CODEC_ID_PCM_ZORK: n = buf_size; for(;n>0;n--) { int x= *src++; if(x&128) x-= 128; else x = -x; *samples++ = x << 8; } break; case CODEC_ID_PCM_ALAW: case CODEC_ID_PCM_MULAW: n = buf_size; for(;n>0;n--) { *samples++ = s->table[*src++]; } break; default: return -1; } *data_size = (uint8_t *)samples - (uint8_t *)data; return src - buf;}#ifdef CONFIG_ENCODERS#define PCM_ENCODER(id,name) \AVCodec name ## _encoder = { \ #name, \ CODEC_TYPE_AUDIO, \ id, \ 0, \ pcm_encode_init, \ pcm_encode_frame, \ pcm_encode_close, \ NULL, \};#else#define PCM_ENCODER(id,name)#endif#ifdef CONFIG_DECODERS#define PCM_DECODER(id,name) \AVCodec name ## _decoder = { \ #name, \ CODEC_TYPE_AUDIO, \ id, \ sizeof(PCMDecode), \ pcm_decode_init, \ NULL, \ NULL, \ pcm_decode_frame, \};#else#define PCM_DECODER(id,name)#endif#define PCM_CODEC(id, name) \PCM_ENCODER(id,name) PCM_DECODER(id,name)PCM_CODEC (CODEC_ID_PCM_S32LE, pcm_s32le);PCM_CODEC (CODEC_ID_PCM_S32BE, pcm_s32be);PCM_CODEC (CODEC_ID_PCM_U32LE, pcm_u32le);PCM_CODEC (CODEC_ID_PCM_U32BE, pcm_u32be);PCM_CODEC (CODEC_ID_PCM_S24LE, pcm_s24le);PCM_CODEC (CODEC_ID_PCM_S24BE, pcm_s24be);PCM_CODEC (CODEC_ID_PCM_U24LE, pcm_u24le);PCM_CODEC (CODEC_ID_PCM_U24BE, pcm_u24be);PCM_CODEC (CODEC_ID_PCM_S24DAUD, pcm_s24daud);PCM_CODEC (CODEC_ID_PCM_S16LE, pcm_s16le);PCM_DECODER(CODEC_ID_PCM_S16LE_PLANAR, pcm_s16le_planar);PCM_CODEC (CODEC_ID_PCM_S16BE, pcm_s16be);PCM_CODEC (CODEC_ID_PCM_U16LE, pcm_u16le);PCM_CODEC (CODEC_ID_PCM_U16BE, pcm_u16be);PCM_CODEC (CODEC_ID_PCM_S8, pcm_s8);PCM_CODEC (CODEC_ID_PCM_U8, pcm_u8);PCM_CODEC (CODEC_ID_PCM_ALAW, pcm_alaw);PCM_CODEC (CODEC_ID_PCM_MULAW, pcm_mulaw);PCM_CODEC (CODEC_ID_PCM_ZORK, pcm_zork);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -