/* * Class: com_jpou_meditor_ffmpeg_trans * Method: startTrans * Signature: (Ljava/lang/String;Ljava/lang/String;)Z */ JNIEXPORT jboolean JNICALL Java_com_jpou_ffmpeg_Transcoding_startTrans (JNIEnv *env, jobject clazz, jstring input, jstring output) { int ret; AVPacket packet = { .data = NULL, .size = 0 }; AVFrame *frame = NULL; enum AVMediaType type; unsigned int stream_index; unsigned int i; int got_frame; int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *); char *input_str, *output_str; input_str = (*env)->GetStringUTFChars(env, input, 0); output_str = (*env)->GetStringUTFChars(env, output, 0); LOGI("input_str ~ : %s -------------------", input_str); LOGI("output_str ~ : %s -------------------", output_str); if ((input == NULL) || (output == NULL)) { LOGI("input_str or output_str is null"); return (jboolean)0; } av_register_all(); avfilter_register_all(); if ((ret = open_input_file(input_str)) < 0) { LOGI("open_input_file error"); goto end; } if ((ret = open_output_file(output_str)) < 0) { LOGI("open_output_file error"); goto end; } LOGI("init_filters ----------------"); if ((ret = init_filters()) < 0) { LOGI("init_filters error"); goto end; } /* read all packets */ LOGI("start av_read_frame ----------------"); while (1) { if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0) break; stream_index = packet.stream_index; type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type; LOGI("Demuxer gave frame of stream_index %u\n", stream_index); if (filter_ctx[stream_index].filter_graph) { av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n"); frame = av_frame_alloc(); if (!frame) { ret = AVERROR(ENOMEM); break; } av_packet_rescale_ts(&packet, ifmt_ctx->streams[stream_index]->time_base, ifmt_ctx->streams[stream_index]->codec->time_base); dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 : avcodec_decode_audio4; ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame, &got_frame, &packet); if (ret < 0) { av_frame_free(&frame); LOGI("Decoding failed\n"); break; } if (got_frame) { frame->pts = av_frame_get_best_effort_timestamp(frame); ret = filter_encode_write_frame(frame, stream_index); av_frame_free(&frame); if (ret < 0) goto end; } else { av_frame_free(&frame); } } else { /* remux this frame without reencoding */ av_packet_rescale_ts(&packet, ifmt_ctx->streams[stream_index]->time_base, ofmt_ctx->streams[stream_index]->time_base); ret = av_interleaved_write_frame(ofmt_ctx, &packet); if (ret < 0) goto end; } av_free_packet(&packet); } /* flush filters and encoders */ for (i = 0; i < ifmt_ctx->nb_streams; i++) { /* flush filter */ if (!filter_ctx[i].filter_graph) continue; ret = filter_encode_write_frame(NULL, i); if (ret < 0) { LOGI("Flushing filter failed\n"); goto end; } /* flush encoder */ ret = flush_encoder(i); if (ret < 0) { LOGI("Flushing encoder failed\n"); goto end; } } av_write_trailer(ofmt_ctx); return (jboolean)1; end: av_free_packet(&packet); av_frame_free(&frame); for (i = 0; i < ifmt_ctx->nb_streams; i++) { avcodec_close(ifmt_ctx->streams[i]->codec); if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && ofmt_ctx->streams[i]->codec) avcodec_close(ofmt_ctx->streams[i]->codec); if (filter_ctx && filter_ctx[i].filter_graph) avfilter_graph_free(&filter_ctx[i].filter_graph); } av_free(filter_ctx); avformat_close_input(&ifmt_ctx); if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) avio_closep(&ofmt_ctx->pb); avformat_free_context(ofmt_ctx); /** if (ret < 0) av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret)); */ return (jboolean)0; } #ifdef __cplusplus }
int main_dummy(int argc, char **argv) #endif { AVOutputFormat *ofmt = NULL; AVFormatContext *inVideoFmtCtx = NULL, *inAudioFmtCtx = NULL, *outFmtCtx = NULL; AVPacket pkt; const char *inVideo_filename, *inAudio_filename, *out_filename; int ret, i; if (argc < 3) { printf("usage: %s input output\n" "API example program to remux a media file with libavformat and libavcodec.\n" "The output format is guessed according to the file extension.\n" "\n", argv[0]); return 1; } inVideo_filename = argv[1]; inAudio_filename = argv[2]; out_filename = argv[3]; av_register_all(); /* =============== OPEN STREAMS ================*/ if ((ret = open_input_file2(argv[1], &inVideoFmtCtx)) < 0) goto end; if ((ret = open_input_file2(argv[2], &inAudioFmtCtx)) < 0) goto end; /* ========== ALLOCATE OUTPUT CONTEXT ==========*/ avformat_alloc_output_context2(&outFmtCtx, NULL, NULL, out_filename); if (!outFmtCtx) { fprintf(stderr, "Could not create output context\n"); ret = AVERROR_UNKNOWN; goto end; } ofmt = outFmtCtx->oformat; /* =============== SETUP VIDEO CODEC ================*/ for (i = 0; i < inVideoFmtCtx->nb_streams; i++) { AVStream *in_stream = inVideoFmtCtx->streams[i]; AVStream *out_stream = avformat_new_stream(outFmtCtx, in_stream->codec->codec); if (!out_stream) { fprintf(stderr, "Failed allocating output stream\n"); ret = AVERROR_UNKNOWN; goto end; } ret = avcodec_copy_context(out_stream->codec, in_stream->codec); if (ret < 0) { fprintf(stderr, "Failed to copy context from input to output stream codec context\n"); goto end; } out_stream->codec->codec_tag = 0; if (outFmtCtx->oformat->flags & AVFMT_GLOBALHEADER) out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; } /* =============== SETUP AUDIO CODEC ================*/ for (i = 0; i < inAudioFmtCtx->nb_streams; i++) { setup_mp3_audio_codec(outFmtCtx); } av_dump_format(outFmtCtx, 0, out_filename, 1); if (!(ofmt->flags & AVFMT_NOFILE)) { ret = avio_open(&outFmtCtx->pb, out_filename, AVIO_FLAG_WRITE); if (ret < 0) { fprintf(stderr, "Could not open output file '%s'", out_filename); goto end; } } ret = avformat_write_header(outFmtCtx, NULL); if (ret < 0) { fprintf(stderr, "Error occurred when opening output file\n"); goto end; } /* =============== SETUP FILTERS ================*/ init_filters(inAudioFmtCtx, outFmtCtx); AVStream *in_stream, *out_stream; AVFrame* frame; while (1) { /* =============== VIDEO STREAM ================*/ ret = av_read_frame(inVideoFmtCtx, &pkt); if (ret < 0) break; in_stream = inVideoFmtCtx->streams[pkt.stream_index]; out_stream = outFmtCtx->streams[pkt.stream_index]; log_packet(inVideoFmtCtx, &pkt, "in"); /* copy packet */ pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); pkt.duration = (int)av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base); pkt.pos = -1; log_packet(outFmtCtx, &pkt, "out"); ret = av_interleaved_write_frame(outFmtCtx, &pkt); if (ret < 0) { fprintf(stderr, "Error muxing packet\n"); break; } av_free_packet(&pkt); /* =============== AUDIO STREAM ================*/ #if 0 ret = av_read_frame(inAudioFmtCtx, &pkt); if (ret < 0) break; in_stream = inAudioFmtCtx->streams[pkt.stream_index]; pkt.stream_index++; out_stream = outFmtCtx->streams[pkt.stream_index]; log_packet(inAudioFmtCtx, &pkt, "in"); /* copy packet */ pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base); pkt.pos = -1; log_packet(outFmtCtx, &pkt, "out"); ret = av_interleaved_write_frame(outFmtCtx, &pkt); if (ret < 0) { fprintf(stderr, "Error muxing packet\n"); break; } av_free_packet(&pkt); #else if ((ret = av_read_frame(inAudioFmtCtx, &pkt)) < 0) break; int streamIndex = pkt.stream_index; int gotFrame; if (_filterCtx[streamIndex].FilterGraph) { av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n"); frame = av_frame_alloc(); if (!frame) { ret = AVERROR(ENOMEM); break; } av_packet_rescale_ts(&pkt, inAudioFmtCtx->streams[streamIndex]->time_base, inAudioFmtCtx->streams[streamIndex]->codec->time_base); ret = avcodec_decode_audio4(inAudioFmtCtx->streams[streamIndex]->codec, frame, &gotFrame, &pkt); if (ret < 0) { av_frame_free(&frame); av_log(NULL, AV_LOG_ERROR, "Decoding failed\n"); break; } if (gotFrame) { frame->pts = av_frame_get_best_effort_timestamp(frame); ret = filter_encode_write_frame(frame, inAudioFmtCtx, outFmtCtx, streamIndex); av_frame_free(&frame); if (ret < 0) goto end; } else { av_frame_free(&frame); } } else { /* remux this frame without reencoding */ av_packet_rescale_ts(&pkt, inAudioFmtCtx->streams[streamIndex]->time_base, outFmtCtx->streams[streamIndex+1]->time_base); ret = av_interleaved_write_frame(outFmtCtx, &pkt); if (ret < 0) goto end; } av_free_packet(&pkt); #endif // 0 } av_write_trailer(outFmtCtx); end: av_free_packet(&pkt); av_frame_free(&frame); for (i = 0; i < inAudioFmtCtx->nb_streams; i++) { avcodec_close(inAudioFmtCtx->streams[i]->codec); if (outFmtCtx && outFmtCtx->nb_streams > i && outFmtCtx->streams[i] && outFmtCtx->streams[i]->codec) avcodec_close(outFmtCtx->streams[i]->codec); if (_filterCtx && _filterCtx[i].FilterGraph) avfilter_graph_free(&_filterCtx[i].FilterGraph); } av_free(_filterCtx); avformat_close_input(&inVideoFmtCtx); avformat_close_input(&inAudioFmtCtx); /* close output */ if (outFmtCtx && !(ofmt->flags & AVFMT_NOFILE)) avio_closep(&outFmtCtx->pb); avformat_free_context(outFmtCtx); if (ret < 0 && ret != AVERROR_EOF) { //fprintf(stderr, "Error occurred: %s\n", av_err2str(ret)); return 1; } return 0; }
int main(int argc, char **argv) { int ret; AVPacket packet = { .data = NULL, .size = 0 }; AVFrame *frame = NULL; enum AVMediaType type; unsigned int stream_index; unsigned int i; int got_frame; int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *); if (argc != 3) { av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <output file>\n", argv[0]); return 1; } av_register_all(); avfilter_register_all(); if ((ret = open_input_file(argv[1])) < 0) goto end; if ((ret = open_output_file(argv[2])) < 0) goto end; if ((ret = init_filters()) < 0) goto end; /* read all packets */ while (1) { if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0) break; stream_index = packet.stream_index; type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type; av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n", stream_index); if (filter_ctx[stream_index].filter_graph) { av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n"); frame = av_frame_alloc(); if (!frame) { ret = AVERROR(ENOMEM); break; } av_packet_rescale_ts(&packet, ifmt_ctx->streams[stream_index]->time_base, ifmt_ctx->streams[stream_index]->codec->time_base); dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 : avcodec_decode_audio4; ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame, &got_frame, &packet); if (ret < 0) { av_frame_free(&frame); av_log(NULL, AV_LOG_ERROR, "Decoding failed\n"); break; } if (got_frame) { frame->pts = av_frame_get_best_effort_timestamp(frame); ret = filter_encode_write_frame(frame, stream_index); av_frame_free(&frame); if (ret < 0) goto end; } else { av_frame_free(&frame); } } else { /* remux this frame without reencoding */ av_packet_rescale_ts(&packet, ifmt_ctx->streams[stream_index]->time_base, ofmt_ctx->streams[stream_index]->time_base); ret = av_interleaved_write_frame(ofmt_ctx, &packet); if (ret < 0) goto end; } av_packet_unref(&packet); } /* flush filters and encoders */ for (i = 0; i < ifmt_ctx->nb_streams; i++) { /* flush filter */ if (!filter_ctx[i].filter_graph) continue; ret = filter_encode_write_frame(NULL, i); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Flushing filter failed\n"); goto end; } /* flush encoder */ ret = flush_encoder(i); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n"); goto end; } } av_write_trailer(ofmt_ctx); end: av_packet_unref(&packet); av_frame_free(&frame); for (i = 0; i < ifmt_ctx->nb_streams; i++) { avcodec_close(ifmt_ctx->streams[i]->codec); if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && ofmt_ctx->streams[i]->codec) avcodec_close(ofmt_ctx->streams[i]->codec); if (filter_ctx && filter_ctx[i].filter_graph) avfilter_graph_free(&filter_ctx[i].filter_graph); } av_free(filter_ctx); avformat_close_input(&ifmt_ctx); if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) avio_closep(&ofmt_ctx->pb); avformat_free_context(ofmt_ctx); if (ret < 0) av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret)); return ret ? 1 : 0; }