mirror of https://github.com/mpv-player/mpv
support for 24 bit pcm/wav files
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12479 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
571c94b3a7
commit
9a43e3adbe
|
@ -131,9 +131,9 @@ char* fmt2str(int format, char* str, size_t size)
|
|||
// Sanity check for bytes per sample
|
||||
int check_bps(int bps)
|
||||
{
|
||||
if(bps != 4 && bps != 2 && bps != 1){
|
||||
if(bps != 4 && bps != 3 && bps != 2 && bps != 1){
|
||||
af_msg(AF_MSG_ERROR,"[format] The number of bytes per sample"
|
||||
" must be 1, 2 or 4. Current value is %i \n",bps);
|
||||
" must be 1, 2, 3 or 4. Current value is %i \n",bps);
|
||||
return AF_ERROR;
|
||||
}
|
||||
return AF_OK;
|
||||
|
@ -349,6 +349,30 @@ af_info_t af_info_format = {
|
|||
open
|
||||
};
|
||||
|
||||
static inline uint32_t load24bit(void* data, int pos) {
|
||||
#if WORDS_BIGENDIAN
|
||||
return (((uint32_t)((uint8_t*)data)[3*pos])<<24) |
|
||||
(((uint32_t)((uint8_t*)data)[3*pos+1])<<16) |
|
||||
(((uint32_t)((uint8_t*)data)[3*pos+2])<<8);
|
||||
#else
|
||||
return (((uint32_t)((uint8_t*)data)[3*pos])<<8) |
|
||||
(((uint32_t)((uint8_t*)data)[3*pos+1])<<16) |
|
||||
(((uint32_t)((uint8_t*)data)[3*pos+2])<<24);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void store24bit(void* data, int pos, uint32_t expanded_value) {
|
||||
#if WORDS_BIGENDIAN
|
||||
((uint8_t*)data)[3*pos]=expanded_value>>24;
|
||||
((uint8_t*)data)[3*pos+1]=expanded_value>>16;
|
||||
((uint8_t*)data)[3*pos+2]=expanded_value>>8;
|
||||
#else
|
||||
((uint8_t*)data)[3*pos]=expanded_value>>8;
|
||||
((uint8_t*)data)[3*pos+1]=expanded_value>>16;
|
||||
((uint8_t*)data)[3*pos+2]=expanded_value>>24;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Function implementations used by play
|
||||
static void endian(void* in, void* out, int len, int bps)
|
||||
{
|
||||
|
@ -362,6 +386,15 @@ static void endian(void* in, void* out, int len, int bps)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case(3):{
|
||||
register uint8_t s;
|
||||
for(i=0;i<len;i++){
|
||||
s=((uint8_t*)in)[3*i];
|
||||
((uint8_t*)out)[3*i]=((uint8_t*)in)[3*i+2];
|
||||
((uint8_t*)out)[3*i+2]=s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(4):{
|
||||
register uint32_t s;
|
||||
for(i=0;i<len;i++){
|
||||
|
@ -388,6 +421,10 @@ static void si2us(void* in, void* out, int len, int bps)
|
|||
for(i=0;i<len;i++)
|
||||
((uint16_t*)out)[i]=(uint16_t)(SHRT_MAX+((int)((int16_t*)in)[i]));
|
||||
break;
|
||||
case(3):
|
||||
for(i=0;i<len;i++)
|
||||
store24bit(out, i, (uint32_t)(INT_MAX+(int32_t)load24bit(in, i)));
|
||||
break;
|
||||
case(4):
|
||||
for(i=0;i<len;i++)
|
||||
((uint32_t*)out)[i]=(uint32_t)(INT_MAX+((int32_t*)in)[i]);
|
||||
|
@ -407,6 +444,10 @@ static void us2si(void* in, void* out, int len, int bps)
|
|||
for(i=0;i<len;i++)
|
||||
((int16_t*)out)[i]=(int16_t)(SHRT_MIN+((int)((uint16_t*)in)[i]));
|
||||
break;
|
||||
case(3):
|
||||
for(i=0;i<len;i++)
|
||||
store24bit(out, i, (int32_t)(INT_MIN+(uint32_t)load24bit(in, i)));
|
||||
break;
|
||||
case(4):
|
||||
for(i=0;i<len;i++)
|
||||
((int32_t*)out)[i]=(int32_t)(INT_MIN+((uint32_t*)in)[i]);
|
||||
|
@ -424,6 +465,10 @@ static void change_bps(void* in, void* out, int len, int inbps, int outbps)
|
|||
for(i=0;i<len;i++)
|
||||
((uint16_t*)out)[i]=((uint16_t)((uint8_t*)in)[i])<<8;
|
||||
break;
|
||||
case(3):
|
||||
for(i=0;i<len;i++)
|
||||
store24bit(out, i, ((uint32_t)((uint8_t*)in)[i])<<24);
|
||||
break;
|
||||
case(4):
|
||||
for(i=0;i<len;i++)
|
||||
((uint32_t*)out)[i]=((uint32_t)((uint8_t*)in)[i])<<24;
|
||||
|
@ -436,12 +481,32 @@ static void change_bps(void* in, void* out, int len, int inbps, int outbps)
|
|||
for(i=0;i<len;i++)
|
||||
((uint8_t*)out)[i]=(uint8_t)((((uint16_t*)in)[i])>>8);
|
||||
break;
|
||||
case(3):
|
||||
for(i=0;i<len;i++)
|
||||
store24bit(out, i, ((uint32_t)((uint16_t*)in)[i])<<16);
|
||||
break;
|
||||
case(4):
|
||||
for(i=0;i<len;i++)
|
||||
((uint32_t*)out)[i]=((uint32_t)((uint16_t*)in)[i])<<16;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case(3):
|
||||
switch(outbps){
|
||||
case(1):
|
||||
for(i=0;i<len;i++)
|
||||
((uint8_t*)out)[i]=(uint8_t)(load24bit(in, i)>>24);
|
||||
break;
|
||||
case(2):
|
||||
for(i=0;i<len;i++)
|
||||
((uint16_t*)out)[i]=(uint16_t)(load24bit(in, i)>>16);
|
||||
break;
|
||||
case(4):
|
||||
for(i=0;i<len;i++)
|
||||
((uint32_t*)out)[i]=(uint32_t)load24bit(in, i);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case(4):
|
||||
switch(outbps){
|
||||
case(1):
|
||||
|
@ -452,6 +517,10 @@ static void change_bps(void* in, void* out, int len, int inbps, int outbps)
|
|||
for(i=0;i<len;i++)
|
||||
((uint16_t*)out)[i]=(uint16_t)((((uint32_t*)in)[i])>>16);
|
||||
break;
|
||||
case(3):
|
||||
for(i=0;i<len;i++)
|
||||
store24bit(out, i, ((uint32_t*)in)[i]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -469,6 +538,10 @@ static void float2int(void* in, void* out, int len, int bps)
|
|||
for(i=0;i<len;i++)
|
||||
((int16_t*)out)[i]=(int16_t)lrintf(SHRT_MAX*((float*)in)[i]);
|
||||
break;
|
||||
case(3):
|
||||
for(i=0;i<len;i++)
|
||||
store24bit(out, i, (int32_t)lrintf(INT_MAX*((float*)in)[i]));
|
||||
break;
|
||||
case(4):
|
||||
for(i=0;i<len;i++)
|
||||
((int32_t*)out)[i]=(int32_t)lrintf(INT_MAX*((float*)in)[i]);
|
||||
|
@ -488,6 +561,10 @@ static void int2float(void* in, void* out, int len, int bps)
|
|||
for(i=0;i<len;i++)
|
||||
((float*)out)[i]=(1.0/SHRT_MAX)*((float)((int16_t*)in)[i]);
|
||||
break;
|
||||
case(3):
|
||||
for(i=0;i<len;i++)
|
||||
((float*)out)[i]=(1.0/INT_MAX)*((float)((int32_t)load24bit(in, i)));
|
||||
break;
|
||||
case(4):
|
||||
for(i=0;i<len;i++)
|
||||
((float*)out)[i]=(1.0/INT_MAX)*((float)((int32_t*)in)[i]);
|
||||
|
|
|
@ -35,6 +35,10 @@ int af_format_decode(int ifmt)
|
|||
case(AFMT_FLOAT):
|
||||
ofmt = AF_FORMAT_F | AF_FORMAT_NE; break;
|
||||
default:
|
||||
if (ifmt & AFMT_AF_FLAGS == AFMT_AF_FLAGS) {
|
||||
ofmt = ifmt & ~AFMT_AF_FLAGS;
|
||||
break;
|
||||
}
|
||||
//This can not happen ....
|
||||
af_msg(AF_MSG_FATAL,"Unrecognized input audio format %i\n",ifmt);
|
||||
break;
|
||||
|
@ -75,6 +79,6 @@ int af_format_encode(void* fmtp)
|
|||
case AF_FORMAT_AC3: return AFMT_AC3;
|
||||
case AF_FORMAT_IMA_ADPCM: return AFMT_IMA_ADPCM;
|
||||
}
|
||||
return AFMT_S16_LE; // shouldn't happen
|
||||
return (fmt->format | AFMT_AF_FLAGS);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,3 +53,8 @@
|
|||
#ifndef AFMT_FLOAT
|
||||
# define AFMT_FLOAT 0x00004000
|
||||
#endif
|
||||
|
||||
/* for formats that don't have a corresponding AFMT_* type,
|
||||
* use the flags from libaf/af_format.h or'ed with this */
|
||||
#define AFMT_AF_FLAGS 0x70000000
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "ad_internal.h"
|
||||
#include "../libaf/af_format.h"
|
||||
|
||||
static ad_info_t info =
|
||||
{
|
||||
|
@ -29,6 +30,9 @@ static int init(sh_audio_t *sh_audio)
|
|||
switch (sh_audio->samplesize) {
|
||||
case 1: sh_audio->sample_format=AFMT_U8; break;
|
||||
case 2: sh_audio->sample_format=AFMT_S16_LE; break;
|
||||
case 3: sh_audio->sample_format=AFMT_AF_FLAGS | AF_FORMAT_I |
|
||||
AF_FORMAT_LE | AF_FORMAT_SI;
|
||||
break;
|
||||
case 4: sh_audio->sample_format=AFMT_S32_LE; break;
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue