/*********************************************************************** * Close *********************************************************************** * **********************************************************************/ void encac3Close( hb_work_object_t * w ) { hb_work_private_t * pv = w->private_data; if ( pv ) { if( pv->context ) { hb_deep_log( 2, "encac3: closing libavcodec" ); if ( pv->context->codec ) avcodec_flush_buffers( pv->context ); hb_avcodec_close( pv->context ); } if ( pv->buf ) { free( pv->buf ); pv->buf = NULL; } if ( pv->samples ) { free( pv->samples ); pv->samples = NULL; } if ( pv->list ) hb_list_empty( &pv->list ); free( pv ); w->private_data = NULL; } }
static void encavcodecaClose(hb_work_object_t * w) { hb_work_private_t * pv = w->private_data; if (pv != NULL) { if (pv->context != NULL) { Finalize(w); hb_deep_log(2, "encavcodeca: closing libavcodec"); if (pv->context->codec != NULL) avcodec_flush_buffers(pv->context); hb_avcodec_close(pv->context); av_free( pv->context ); } if (pv->output_buf != NULL) { free(pv->output_buf); } if (pv->input_buf != NULL && pv->input_buf != pv->output_buf) { free(pv->input_buf); } pv->output_buf = pv->input_buf = NULL; if (pv->list != NULL) { hb_list_empty(&pv->list); } if (pv->avresample != NULL) { avresample_free(&pv->avresample); } free(pv); w->private_data = NULL; } }
static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i ) { hb_work_object_t * w; hb_work_private_t * pv; hb_sync_audio_t * sync; pv = calloc( 1, sizeof( hb_work_private_t ) ); sync = &pv->type.audio; sync->index = i; pv->job = job; pv->common = common; pv->common->ref++; pv->common->pts_count++; w = hb_get_work( WORK_SYNC_AUDIO ); w->private_data = pv; w->audio = hb_list_item( job->list_audio, i ); w->fifo_in = w->audio->priv.fifo_raw; if ( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG ) { w->fifo_out = w->audio->priv.fifo_out; } else { w->fifo_out = w->audio->priv.fifo_sync; } if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS || w->audio->config.out.codec == HB_ACODEC_AAC_PASS ) { /* Have a silent AC-3/AAC frame ready in case we have to fill a gap */ AVCodec * codec; AVCodecContext * c; switch ( w->audio->config.out.codec ) { case HB_ACODEC_AC3_PASS: { codec = avcodec_find_encoder( AV_CODEC_ID_AC3 ); } break; case HB_ACODEC_AAC_PASS: { codec = avcodec_find_encoder( AV_CODEC_ID_AAC ); } break; default: { // Never gets here codec = NULL; // Silence compiler warning } break; } c = avcodec_alloc_context3(codec); c->bit_rate = w->audio->config.in.bitrate; c->sample_rate = w->audio->config.in.samplerate; c->channels = av_get_channel_layout_nb_channels(w->audio->config.in.channel_layout); hb_ff_set_sample_fmt(c, codec, AV_SAMPLE_FMT_FLT); if (w->audio->config.in.channel_layout == AV_CH_LAYOUT_STEREO_DOWNMIX) { c->channel_layout = AV_CH_LAYOUT_STEREO; } else { c->channel_layout = w->audio->config.in.channel_layout; } if( hb_avcodec_open( c, codec, NULL, 0 ) < 0 ) { hb_log( "sync: avcodec_open failed" ); return; } // Prepare input frame AVFrame frame = { .nb_samples = c->frame_size, .pts = 0, }; int input_size = av_samples_get_buffer_size(NULL, c->channels, frame.nb_samples, c->sample_fmt, 1); uint8_t *zeros = calloc(1, input_size); avcodec_fill_audio_frame(&frame, c->channels, c->sample_fmt, zeros, input_size, 1); // Allocate enough space for the encoded silence // The output should be < the input sync->silence_buf = malloc( input_size ); // There is some delay in getting output from some audio encoders. // So encode a few packets till we get output. int ii; for ( ii = 0; ii < 10; ii++ ) { // Prepare output packet AVPacket pkt; int got_packet; av_init_packet(&pkt); pkt.data = sync->silence_buf; pkt.size = input_size; int ret = avcodec_encode_audio2( c, &pkt, &frame, &got_packet); if ( ret < 0 ) { hb_log( "sync: avcodec_encode_audio failed" ); break; } if ( got_packet ) { sync->silence_size = pkt.size; break; } } free( zeros ); hb_avcodec_close( c ); av_free( c ); } else { if( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG )