这个方法中哪里有问题呢,我使用它 ,会在 第一个 ret<0的地方跳出循环,导致压缩失败
extern "C"{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include "libx265/x265.h"
#include "libavutil/imgutils.h"
}
extern "C" JNIEXPORT int JNICALL
Java_com_kw_ffapplication_MainActivity_compressVideo(JNIEnv *env, jobject thiz, jstring input_path, jstring output_path) {
const char *in_filename = env->GetStringUTFChars(input_path, nullptr);
const char *out_filename = env->GetStringUTFChars(output_path, nullptr);
AVFormatContext *format_ctx = avformat_alloc_context();
if (avformat_open_input(&format_ctx, in_filename, nullptr, nullptr) != 0) {
printf("ADD", "FFmpeg", "Error opening input file");
return -1;
}
// Find the input video stream
int in_stream_index = -1;
for (int i = 0; i < format_ctx->nb_streams; i++) {
if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
in_stream_index = i;
break;
}
}
if (in_stream_index == -1) {
printf("ADD", "FFmpeg", "Could not find input video stream");
return -1;
}
AVStream *in_stream = format_ctx->streams[in_stream_index];
x265_param param;
x265_param_default(¶m);
param.sourceWidth = in_stream->codecpar->width; // Set width of input video
param.sourceHeight = in_stream->codecpar->height; // Set height of input video
param.fpsNum = 60;
param.fpsDenom = 1;
param.frameNumThreads = 1;
x265_encoder* encoder = x265_encoder_open(¶m);
if (!encoder) {
// Error handling
return -1;
}
// Initialize decoder
AVCodec *dec = const_cast<AVCodec *>(avcodec_find_decoder(in_stream->codecpar->codec_id));
AVCodecContext *dec_ctx = avcodec_alloc_context3(dec);
avcodec_parameters_to_context(dec_ctx, in_stream->codecpar);
avcodec_open2(dec_ctx, dec, nullptr);
// Compression loop
AVPacket *pkt = av_packet_alloc();
AVFrame *frame = av_frame_alloc();
int ret;
while (av_read_frame(format_ctx, pkt) >= 0) {
if (pkt->stream_index == in_stream_index) {
// Decode the video packet
avcodec_send_packet(dec_ctx, pkt);
ret = avcodec_receive_frame(dec_ctx, frame);
if (ret < 0) {
// Error handling
printf("sssssssssssssssssssssssssssssssssssssssssssssssssssssssss%lld\n", (long long)ret); // 100
break;
}
// Compress the frame
x265_nal *nal;
int i_nal;
ret = x265_encoder_encode(encoder, &nal, reinterpret_cast<uint32_t *>(&i_nal),
reinterpret_cast<x265_picture *>(frame), nullptr);
if (ret < 0) {
// Error handling
break;
}
// Write compressed data to output file
for (int i = 0; i < i_nal; i++) {
AVPacket out_pkt;
av_init_packet(&out_pkt);
out_pkt.data = nal[i].payload;
out_pkt.size = nal[i].sizeBytes;
out_pkt.stream_index = 0; // Assuming only one output stream
av_write_frame(format_ctx, &out_pkt);
}
}
av_packet_unref(pkt);
av_frame_unref(frame);
}
// Flush encoder
x265_nal *nal;
int i_nal;
x265_encoder_encode(encoder, &nal, reinterpret_cast<uint32_t *>(&i_nal), nullptr, nullptr);
for (int i = 0; i < i_nal; i++) {
// Write remaining compressed data to output file
// ...
AVPacket out_pkt;
av_init_packet(&out_pkt);
out_pkt.data = nal[i].payload;
out_pkt.size = nal[i].sizeBytes;
out_pkt.stream_index = 0; // Assuming only one output stream
av_write_frame(format_ctx, &out_pkt);
}
// Release decoder
avcodec_free_context(&dec_ctx);
x265_encoder_close(encoder);
// Release resources
av_packet_free(&pkt);
av_frame_free(&frame);
// Close input and output files
avformat_close_input(&format_ctx);
env->ReleaseStringUTFChars(input_path, in_filename);
env->ReleaseStringUTFChars(output_path, out_filename);
return 0;
}