static int decode_audio(sh_audio_t *audio, unsigned char *buf, int minlen, int maxlen) { int len=0; dv_decoder_t* decoder=audio->context; //global_rawdv_decoder; unsigned char* dv_audio_frame=NULL; int xx=ds_get_packet(audio->ds,&dv_audio_frame); if(xx<=0 || !dv_audio_frame) return 0; // EOF? dv_parse_header(decoder, dv_audio_frame); if(xx!=decoder->frame_size) mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[AD_LIBDV] Warning! Audio framesize differs! read=%d hdr=%d.\n", xx, decoder->frame_size); if (dv_decode_full_audio(decoder, dv_audio_frame,(int16_t**) audioBuffers)) { /* Interleave the audio into a single buffer */ int i=0; int16_t *bufP=(int16_t*)buf; // printf("samples=%d/%d chans=%d mem=%d \n",decoder->audio->samples_this_frame,DV_AUDIO_MAX_SAMPLES, // decoder->audio->num_channels, decoder->audio->samples_this_frame*decoder->audio->num_channels*2); // return (44100/30)*4; for (i=0; i < decoder->audio->samples_this_frame; i++) { int ch; for (ch=0; ch < decoder->audio->num_channels; ch++) bufP[len++] = audioBuffers[ch][i]; } } return len*2; }
int dv_read_audio(dv_t *dv, unsigned char *samples, unsigned char *data, long size, int channels, int bits) { long current_position; int norm; int i, j; int audio_bytes; short *samples_int16 = (short*)samples; int samples_read; if(channels > 4) channels = 4; // For some reason someone had problems with libdv's maxmimum audio samples #define MAX_AUDIO_SAMPLES 2048 if(!dv->temp_audio[0]) { for(i = 0; i < 4; i++) dv->temp_audio[i] = calloc(1, sizeof(int16_t) * MAX_AUDIO_SAMPLES); } switch(size) { case DV_PAL_SIZE: norm = DV_PAL; break; case DV_NTSC_SIZE: norm = DV_NTSC; break; default: return 0; break; } if(data[0] != 0x1f) return 0; dv_parse_header(dv->decoder, data); dv_decode_full_audio(dv->decoder, data, dv->temp_audio); samples_read = dv->decoder->audio->samples_this_frame; for(i = 0; i < channels; i++) { for(j = 0; j < samples_read; j++) { samples_int16[i + j * channels] = dv->temp_audio[i][j]; if(samples_int16[i + j * channels] == -0x8000) samples_int16[i + j * channels] = 0; } } return samples_read; }
int DVFrame::ExtractAudio( int16_t **channels ) { AudioInfo info; if ( GetAudioInfo( info ) == true ) dv_decode_full_audio( decoder, data, channels ); else info.samples = 0; return info.samples * info.channels * 2; }
long int lp_libdv_in::read_samples(float *buffer, long int len) { int audio_decoded = 0, file_readen = 0; int i, channel; // std::cerr << "lp_libdv_in::" << __FUNCTION__ << " called\n"; // TESTS len = len/2; /* Interleave the audio into a single buffer */ /* for (i = 0, samples = dv_get_num_samples (dv), channels = dv_get_num_channels (dv); i < samples; i++) { for (ch = 0; ch < channels; ch++) { oss -> buffer [j++] = out [ch] [i]; } } */ // Check if decoding is requierd //while(pv_audio_num_ready <= len){ while(pv_lp_audio_buffer.left() <= len){ file_readen = read(pv_fd, pv_file_buffer, 144000); // FIXME: len to read ? // decode a video frame and display - NOTE this part must move to another class later... dv_decode_full_frame(pv_decoder, pv_file_buffer, pv_color_space, pv_sdl_out->pb_pixels, pv_sdl_out->pb_pitches); pv_sdl_out->display(); // decode audio dv_decode_full_audio(pv_decoder, pv_file_buffer, pv_dv_audio_buffers); audio_decoded = dv_get_num_samples(pv_decoder); // Copy to ready buffer //for(i=0; i<audio_decoded; i++){ for(channel = 0; channel < pv_audio_channels; channel++){ // write to ready buffer from start position //pv_audio_ready_buffer[pv_audio_decoder_start+channel+i*pv_audio_channels] = pv_dv_audio_buffers[channel][i]; pv_lp_audio_buffer.put(pv_dv_audio_buffers[channel], audio_decoded / pv_audio_channels); } //} pv_audio_num_ready = pv_audio_num_ready + audio_decoded; // update start pos pv_audio_decoder_start = pv_audio_decoder_start + audio_decoded; } pv_lp_audio_buffer.get(pv_audio_ready_buffer, len); float tmp; // Copy needed to output buffer for(i=0; i<len; i++){ //buffer[i] = (float)(pv_audio_ready_buffer[pv_audio_decoder_start+i] / 32768); //buffer[i] = (float)(pv_audio_ready_buffer[pv_audio_decoder_start+i] / 4000); tmp = (float)pv_audio_ready_buffer[i]; buffer[i] = tmp / 6000.0; //buffer[i] = (float)(pv_audio_ready_buffer[i] / 6000); } // update start pos pv_audio_consumer_start = pv_audio_decoder_start + len; // Calcule samples consomés pv_audio_num_ready = pv_audio_num_ready - len; // On déplace le reste au début de pv_audio_ready buffer /* if(pv_audio_num_ready > 0){ for(i=0; i<pv_audio_num_ready; i++){ pv_audio_ready_buffer[i] = pv_audio_ready_buffer[pv_audio_decoder_start+i]; } // reset positions pv_audio_decoder_start = 0; pv_audio_consumer_start = 0; } */ // std::cout << "Décodés: " << pv_audio_num_ready << " - consommés: " << len << " - prêts: " << pv_audio_num_ready << "\n"; // std::cout << "Start decodeur: " << pv_audio_decoder_start << " - start consumer: " << pv_audio_consumer_start << "\n\n"; // THIS is false ! //return file_readen; return len; }
int main( int argc, char **argv) { int infile = 0; unsigned char dv_buffer[144000]; unsigned char video_buffer[720 * 576 * 3]; int16_t *audio_bufs[4]; dv_decoder_t *decoder = NULL; dv_encoder_t *encoder = NULL; int pitches[3]; unsigned char *pixels[3]; int i = 0, j; int isPAL = FALSE; pitches[0] = 720 * 2; pixels[0] = video_buffer; for(i = 0; i < 4; i++) { audio_bufs[i] = malloc(DV_AUDIO_MAX_SAMPLES*sizeof(int16_t)); } /* assume NTSC for now, switch to PAL later if needed */ decoder = dv_decoder_new(FALSE, FALSE, FALSE); encoder = dv_encoder_new(FALSE, FALSE, FALSE); decoder->quality = DV_QUALITY_BEST; encoder->vlc_encode_passes = 3; encoder->static_qno = 0; encoder->force_dct = DV_DCT_AUTO; i = 0; while (read_frame(stdin, dv_buffer, &isPAL)) { dv_parse_header(decoder, dv_buffer); if (isPAL != encoder->isPAL && isPAL == TRUE) { decoder->clamp_luma = FALSE; decoder->clamp_chroma = FALSE; encoder->clamp_luma = FALSE; encoder->clamp_chroma = FALSE; dv_reconfigure(FALSE, FALSE); } else if (isPAL != encoder->isPAL) { decoder->clamp_luma = TRUE; decoder->clamp_chroma = TRUE; decoder->add_ntsc_setup = TRUE; encoder->clamp_luma = TRUE; encoder->clamp_chroma = TRUE; encoder->rem_ntsc_setup = TRUE; dv_reconfigure(TRUE, TRUE); } encoder->isPAL = isPAL; encoder->is16x9 = (dv_format_wide(decoder)>0); dv_decode_full_audio(decoder, dv_buffer, audio_bufs); for (j = 0; j < TIMES; j++) { dv_decode_full_frame(decoder, dv_buffer, e_dv_color_yuv, pixels, pitches); dv_encode_full_frame(encoder, pixels, e_dv_color_yuv, dv_buffer); } dv_encode_full_audio(encoder, audio_bufs, 2, 48000, dv_buffer); fwrite(dv_buffer, 1, (isPAL ? 144000 : 120000), stdout); } close(infile); for(i=0; i < 4; i++) free(audio_bufs[i]); dv_decoder_free(decoder); dv_encoder_free(encoder); return 0; }
int DVFrame::ExtractAudio( void *sound ) { AudioInfo info; if ( GetAudioInfo( info ) == true ) { //#ifdef HAVE_LIBDV int n, i; int16_t* s = ( int16_t * ) sound; dv_decode_full_audio( decoder, data, ( int16_t ** ) audio_buffers ); for ( n = 0; n < info.samples; ++n ) for ( i = 0; i < info.channels; i++ ) *s++ = audio_buffers[ i ][ n ]; } else info.samples = 0; //#else ///* Collect the audio samples */ //char* s = ( char * ) sound; //switch ( info.frequency ) //{ //case 32000: ///* This is 4 channel audio */ //if ( IsPAL() ) //{ //short * p = ( short* ) sound; //for ( int n = 0; n < info.samples; ++n ) //{ //register int r = ( ( unsigned char* ) data ) [ palmap_2ch1[ n ] + 1 ]; // LSB //*p++ = compmap[ ( ( ( unsigned char* ) data ) [ palmap_2ch1[ n ] ] << 4 ) + ( r >> 4 ) ]; // MSB //*p++ = compmap[ ( ( ( unsigned char* ) data ) [ palmap_2ch1[ n ] + 1 ] << 4 ) + ( r & 0x0f ) ]; //} //} //else //{ //short* p = ( short* ) sound; //for ( int n = 0; n < info.samples; ++n ) //{ //register int r = ( ( unsigned char* ) data ) [ ntscmap_2ch1[ n ] + 1 ]; // LSB //*p++ = compmap[ ( ( ( unsigned char* ) data ) [ ntscmap_2ch1[ n ] ] << 4 ) + ( r >> 4 ) ]; // MSB //*p++ = compmap[ ( ( ( unsigned char* ) data ) [ ntscmap_2ch1[ n ] + 1 ] << 4 ) + ( r & 0x0f ) ]; //} //} //break; //case 44100: //case 48000: ///* this can be optimized significantly */ //if ( IsPAL() ) //{ //for ( int n = 0; n < info.samples; ++n ) //{ //*s++ = ( ( char* ) data ) [ palmap_ch1[ n ] + 1 ]; /* LSB */ //*s++ = ( ( char* ) data ) [ palmap_ch1[ n ] ]; /* MSB */ //*s++ = ( ( char* ) data ) [ palmap_ch2[ n ] + 1 ]; /* LSB */ //*s++ = ( ( char* ) data ) [ palmap_ch2[ n ] ]; /* MSB */ //} //} //else //{ //for ( int n = 0; n < info.samples; ++n ) //{ //*s++ = ( ( char* ) data ) [ ntscmap_ch1[ n ] + 1 ]; /* LSB */ //*s++ = ( ( char* ) data ) [ ntscmap_ch1[ n ] ]; /* MSB */ //*s++ = ( ( char* ) data ) [ ntscmap_ch2[ n ] + 1 ]; /* LSB */ //*s++ = ( ( char* ) data ) [ ntscmap_ch2[ n ] ]; /* MSB */ //} //} //break; ///* we can't handle any other format in the moment */ //default: //info.samples = 0; //} //} //else //info.samples = 0; //#endif return info.samples * info.channels * 2; }