mp23codec_libav=NULL;
mp23codec_context_libav=NULL;
+#ifdef USE_LIBRESAMPLE
+ resam_con_libav=NULL;
+#endif
decompress_buffer=NULL;
decompress_buffer_size=0;
libav_mutex.Unlock();
return 0;
}
+#ifdef USE_LIBRESAMPLE
+ resam_con_libav = avresample_alloc_context();
+ if (resam_con_libav == NULL) {
+ Log::getInstance()->log("Audio", Log::DEBUG,
+ "Alloc resample context failed");
+ return 0;
+ }
+
+ av_opt_set_int(resam_con_libav, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); // our standard format
+ av_opt_set_int(resam_con_libav, "out_sample_rate",48000,0);
+ av_opt_set_int(resam_con_libav, "out_sample_fmt",AV_SAMPLE_FMT_S16,0);
+
+ av_opt_set_int(resam_con_libav, "in_sample_rate",48000,0);
+ av_opt_set_int(resam_con_libav, "in_sample_fmt",AV_SAMPLE_FMT_S16,0);
+ av_opt_set_int(resam_con_libav, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); //just an example
+#endif
av_init_packet(&incoming_paket_libav);
decode_frame_libav=avcodec_alloc_frame();
avcodec_close(mp23codec_context_libav);
av_free(mp23codec_context_libav);
mp23codec_context_libav = NULL;
+#ifdef USE_LIBRESAMPLE
+ avresample_free(resam_con_libav);
+ resam_con_libav=NULL;
+#endif
}
libav_mutex.Unlock();
}
return size;
}
+#ifndef USE_LIBRESAMPLE
+#define SQRT3_2 1.22474487139158904909
+void AudioOMX::getDownMixMatrix(unsigned long long channels,
+ double *left_mat,double *right_mat)
+{
+ int i,j;
+ double downmix_matrix[2][64];
+ for (i=0;i<64;i++) {
+ for (j=0;j<2;j++) {
+ downmix_matrix[j][i]=0.;
+ }
+ }
+ downmix_matrix[0/*links*/][/*FRONT_LEFT*/0]=1.;
+ downmix_matrix[1/*rechts*/][/*FRONT_RIGHT*/1]=1.;
+ if (channels & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT) ) {
+ downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2*M_SQRT1_2;
+ downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2*M_SQRT1_2;
+ } else {
+ downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2;
+ downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2;
+ }
+ downmix_matrix[0/*links*/][/*BACK_LEFT*/4 ]=-M_SQRT1_2*SQRT3_2;
+ downmix_matrix[1/*rechts*/][/*BACK_LEFT*/4]=M_SQRT1_2*M_SQRT1_2;
+ downmix_matrix[0/*links*/][/*BACK_RIGHT*/5 ]=-M_SQRT1_2*M_SQRT1_2;
+ downmix_matrix[1/*rechts*/][/*BACK_RIGHT*/5]=M_SQRT1_2*SQRT3_2;
+ downmix_matrix[0/*links*/][/*SIDE_LEFT*/9 ]=-M_SQRT1_2*SQRT3_2;
+ downmix_matrix[1/*rechts*/][/*SIDE_LEFT*/9]=M_SQRT1_2*M_SQRT1_2;
+ downmix_matrix[0/*links*/][/*SIDE_RIGHT*/10 ]=-M_SQRT1_2*M_SQRT1_2;
+ downmix_matrix[1/*rechts*/][/*SIDE_RIGHT*/10]=M_SQRT1_2*SQRT3_2;
+ downmix_matrix[0/*links*/][/*FRONT_LEFT_OF_CENTER*/6]=1.;
+ downmix_matrix[1/*rechts*/][/*FRONT_RIGHT_OF_CENTER*/7]=1.;
+ downmix_matrix[0/*links*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
+ downmix_matrix[1/*rechts*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
+
+ for (i=0,j=0;i<64;i++) {
+ if ((1ULL << i)& channels) {
+ left_mat[j]=downmix_matrix[0][i];
+ right_mat[j]=downmix_matrix[1][i];
+ j++;
+ }
+ }
+}
+
+#endif
void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
{
if (gotta) {
//Log::getInstance()->log("Audio", Log::DEBUG,
// "Got a frame");
+
int dsize = av_samples_get_buffer_size(NULL,
- current_context->channels, decode_frame_libav->nb_samples,
+ /*current_context->channels*/2, decode_frame_libav->nb_samples,
current_context->sample_fmt, 1);
- if (current_context->channels==1) dsize*=2; // we convert mono to stereo
+ int dsize_in = av_samples_get_buffer_size(NULL,
+ current_context->channels, decode_frame_libav->nb_samples,
+ current_context->sample_fmt, 1);
+ //if (current_context->channels==1) dsize*=2; // we convert mono to stereo
if ((cur_input_buf_omx->nFilledLen + dsize)
> cur_input_buf_omx->nAllocLen ) {
// I doubt that this will ever happen
}
//Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
- if (current_context->channels!=1) {
+ if (current_context->channels==2) {
memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
decode_frame_libav->data[0], dsize);
- } else { //convert to stereo
- unsigned short* startbuffer=(unsigned short* )decode_frame_libav->data[0];
- unsigned short* endbuffer=(unsigned short* )(decode_frame_libav->data[0]+dsize/2);
- unsigned short* destbuffer=(unsigned short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
+ }
+#ifndef USE_LIBRESAMPLE
+ else if (current_context->channels==1) { //convert to stereo
+ short* startbuffer=(short* )decode_frame_libav->data[0];
+ short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize/2);
+ short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
while (startbuffer!=endbuffer) {
- unsigned short temp=*startbuffer;
+ unsigned short temp=*startbuffer;
*destbuffer=temp;
destbuffer++;
*destbuffer=temp;
destbuffer++;
startbuffer++;
}
+ } else {
+ unsigned int channels=current_context->channels;
+ double left_mat[channels];
+ double right_mat[channels];
+ getDownMixMatrix(current_context->channel_layout,left_mat,right_mat);
+
+ short* startbuffer=(short* )decode_frame_libav->data[0];
+ short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize_in);
+ short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
+ while (startbuffer!=endbuffer) {
+ short* cur_buf=startbuffer;
+ short* cur_buf_end=startbuffer+channels;
+ double work1=0.;
+ double work2=0.;
+ double *mat1=left_mat;
+ double *mat2=right_mat;
+ while (cur_buf!=cur_buf_end) {
+ work1+= ((*mat1)*((double)*cur_buf));
+ work2+= ((*mat2)*((double)*cur_buf));
+ cur_buf++;
+ mat1++;
+ mat2++;
+ }
+ *destbuffer=work1;
+ destbuffer++;
+ *destbuffer=work2;
+ destbuffer++;
+ startbuffer+=channels;
+
+ }
+
}
+#else
+ else {
+ //untested for future use
+ av_opt_set_int(resam_con_libav, "in_sample_rate",current_context->sample_rate,0);
+ av_opt_set_int(resam_con_libav, "in_sample_fmt",current_context->sample_fmt,0);
+ av_opt_set_int(resam_con_libav, "in_channel_layout",current_context->channel_layout, 0);
+ int ret=avresample_open(resam_con_libav);
+ if (ret<0) {
+ Log::getInstance()->log("Audio", Log::ERR,"Opening AV resample failed %d",ret);
+ } else {
+ avresample_convert(resam_con_libav, cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
+ dsize, decode_frame_libav->nb_samples,
+ decode_frame_libav->data[0], dsize_in, decode_frame_libav->nb_samples);
+ avresample_close(resam_con_libav);
+ }
+
+ }
+#endif
+
//Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
cur_input_buf_omx->nFilledLen += dsize;
} else {