static vod_status_t audio_filter_read_filter_sink(audio_filter_state_t* state) { AVPacket output_packet; vod_status_t rc; int got_packet; int avrc; #ifdef AUDIO_FILTER_DEBUG size_t data_size; #endif // AUDIO_FILTER_DEBUG for (;;) { avrc = av_buffersink_get_frame_flags(state->sink.buffer_sink, state->filtered_frame, AV_BUFFERSINK_FLAG_NO_REQUEST); if (avrc == AVERROR(EAGAIN) || avrc == AVERROR_EOF) { break; } if (avrc < 0) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "audio_filter_read_filter_sink: av_buffersink_get_frame_flags failed %d", avrc); return VOD_UNEXPECTED; } #ifdef AUDIO_FILTER_DEBUG data_size = av_samples_get_buffer_size( NULL, state->sink.encoder->channels, state->filtered_frame->nb_samples, state->sink.encoder->sample_fmt, 1); audio_filter_append_debug_data("sink", "pcm", state->filtered_frame->data[0], data_size); #endif // AUDIO_FILTER_DEBUG av_init_packet(&output_packet); output_packet.data = NULL; // packet data will be allocated by the encoder output_packet.size = 0; got_packet = 0; avrc = avcodec_encode_audio2(state->sink.encoder, &output_packet, state->filtered_frame, &got_packet); av_frame_unref(state->filtered_frame); if (avrc < 0) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "audio_filter_read_filter_sink: avcodec_encode_audio2 failed %d", avrc); return VOD_ALLOC_FAILED; } if (got_packet) { rc = audio_filter_write_frame(state, &output_packet); av_free_packet(&output_packet); if (rc != VOD_OK) { return rc; } } } return VOD_OK; }
static vod_status_t audio_filter_process_frame(audio_filter_state_t* state, u_char* buffer) { audio_filter_source_t* source = state->cur_source; input_frame_t* frame = source->cur_frame; AVPacket input_packet; int got_frame; int avrc; #ifdef AUDIO_FILTER_DEBUG size_t data_size; #endif // AUDIO_FILTER_DEBUG #ifdef AUDIO_FILTER_DEBUG audio_filter_append_debug_data("input", "aac", buffer, frame->size); #endif // AUDIO_FILTER_DEBUG vod_memzero(&input_packet, sizeof(input_packet)); input_packet.data = buffer; input_packet.size = frame->size; input_packet.dts = state->dts; input_packet.pts = state->dts + frame->pts_delay; input_packet.duration = frame->duration; input_packet.flags = AV_PKT_FLAG_KEY; state->dts += frame->duration; av_frame_unref(state->decoded_frame); got_frame = 0; avrc = avcodec_decode_audio4(source->decoder, state->decoded_frame, &got_frame, &input_packet); if (avrc < 0) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "audio_filter_process_frame: avcodec_decode_audio4 failed %d", avrc); return VOD_BAD_DATA; } if (!got_frame) { return VOD_OK; } #ifdef AUDIO_FILTER_DEBUG data_size = av_samples_get_buffer_size( NULL, source->decoder->channels, state->decoded_frame->nb_samples, source->decoder->sample_fmt, 1); audio_filter_append_debug_data(source->buffer_src->name, "pcm", state->decoded_frame->data[0], data_size); #endif // AUDIO_FILTER_DEBUG avrc = av_buffersrc_add_frame_flags(source->buffer_src, state->decoded_frame, AV_BUFFERSRC_FLAG_PUSH); if (avrc < 0) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "audio_filter_process_frame: av_buffersrc_add_frame_flags failed %d", avrc); return VOD_ALLOC_FAILED; } return audio_filter_read_filter_sink(state); }
vod_status_t audio_filter_process_frame(void* context, input_frame_t* frame, u_char* buffer) { audio_filter_state_t* state = (audio_filter_state_t*)context; vod_status_t rc; AVPacket output_packet; AVPacket input_packet; int got_packet; int got_frame; int ret; #ifdef AUDIO_FILTER_DEBUG size_t data_size; #endif // AUDIO_FILTER_DEBUG if (frame == NULL) { return audio_filter_flush_encoder(state); } #ifdef AUDIO_FILTER_DEBUG audio_filter_append_debug_data(AUDIO_FILTER_DEBUG_FILENAME_INPUT, buffer, frame->size); #endif // AUDIO_FILTER_DEBUG vod_memzero(&input_packet, sizeof(input_packet)); input_packet.data = buffer; input_packet.size = frame->size; input_packet.dts = state->dts; input_packet.pts = (state->dts + frame->pts_delay); input_packet.duration = frame->duration; input_packet.flags = AV_PKT_FLAG_KEY; state->dts += frame->duration; avcodec_get_frame_defaults(state->decoded_frame); got_frame = 0; ret = avcodec_decode_audio4(state->decoder, state->decoded_frame, &got_frame, &input_packet); if (ret < 0) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "audio_filter_process_frame: avcodec_decode_audio4 failed %d", ret); return VOD_BAD_DATA; } if (!got_frame) { return VOD_OK; } #ifdef AUDIO_FILTER_DEBUG data_size = av_samples_get_buffer_size( NULL, state->decoder->channels, state->decoded_frame->nb_samples, state->decoder->sample_fmt, 1); audio_filter_append_debug_data(AUDIO_FILTER_DEBUG_FILENAME_DECODED, state->decoded_frame->data[0], data_size); #endif // AUDIO_FILTER_DEBUG ret = av_buffersrc_add_frame_flags(state->buffer_src, state->decoded_frame, AV_BUFFERSRC_FLAG_PUSH); if (ret < 0) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "audio_filter_process_frame: av_buffersrc_add_frame_flags failed %d", ret); return VOD_ALLOC_FAILED; } for (;;) { ret = av_buffersink_get_frame_flags(state->buffer_sink, state->filtered_frame, AV_BUFFERSINK_FLAG_NO_REQUEST); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } if (ret < 0) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "audio_filter_process_frame: av_buffersink_get_frame_flags failed %d", ret); return VOD_UNEXPECTED; } #ifdef AUDIO_FILTER_DEBUG data_size = av_samples_get_buffer_size( NULL, state->encoder->channels, state->filtered_frame->nb_samples, state->encoder->sample_fmt, 1); audio_filter_append_debug_data(AUDIO_FILTER_DEBUG_FILENAME_FILTERED, state->filtered_frame->data[0], data_size); #endif // AUDIO_FILTER_DEBUG av_init_packet(&output_packet); output_packet.data = NULL; // packet data will be allocated by the encoder output_packet.size = 0; got_packet = 0; ret = avcodec_encode_audio2(state->encoder, &output_packet, state->filtered_frame, &got_packet); if (ret < 0) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "audio_filter_process_frame: avcodec_encode_audio2 failed %d", ret); return VOD_ALLOC_FAILED; } if (got_packet) { rc = audio_filter_write_frame(state, &output_packet); av_free_packet(&output_packet); if (rc != VOD_OK) { return rc; } } av_frame_unref(state->filtered_frame); } return VOD_OK; }