单帧

JNIEXPORT jbyteArray JNICALLJava_com_uestc_smileteeth_view_recordvideo_RecordVideoLib_encodeFrame(JNIEnv *env, jclass type,                                                                      jbyteArray yuv420p_,                                                                      jint width, jint height,                                                                      jint index) {    jbyte *yuv420p = (*env)->GetByteArrayElements(env, yuv420p_, NULL);    AVCodec *pCodec;    AVCodecContext *pCodecCtx = NULL;    int i, ret, got_output;    AVFrame *pFrame;    AVPacket pkt;    int y_size;    jbyteArray h264;    //编码格式;    enum AVCodecID codec_id = AV_CODEC_ID_H264;    int in_w = width, in_h = height;    //注册所有编解码器;    avcodec_register_all();    //寻找解码器;    pCodec = avcodec_find_encoder(codec_id);    if (!pCodec) {        LOGI("Codec not found");    }    pCodecCtx = avcodec_alloc_context3(pCodec);    if (!pCodecCtx) {        LOGI("Could not allocate video codec context!");    }    pCodecCtx->bit_rate = 4000000;    pCodecCtx->width = in_w;    pCodecCtx->height = in_h;    pCodecCtx->time_base.num = 1;    pCodecCtx->time_base.den = 25;    pCodecCtx->gop_size = 10;    pCodecCtx->max_b_frames = 0;    pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;    if (codec_id == AV_CODEC_ID_H264) {        av_opt_set(pCodecCtx->priv_data, "preset", "slow", 0);//        av_opt_set(pCodecCtx->priv_data, "preset", "superfast", 0);//        av_opt_set(pCodecCtx->priv_data, "tune", "zerolatency", 0);    }    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {        LOGI("Could not open codec!");    }    pFrame = av_frame_alloc();    if (!pFrame) {        LOGI("Could not allocate video frame!");    }    pFrame->format = pCodecCtx->pix_fmt;    pFrame->width = pCodecCtx->width;    pFrame->height = pCodecCtx->height;    ret = av_image_alloc(pFrame->data, pFrame->linesize, pCodecCtx->width, pCodecCtx->height,                         pCodecCtx->pix_fmt, 16);    if (ret < 0) {        LOGI("Could not allocate raw picture buffer!");    }    y_size = pCodecCtx->width * pCodecCtx->height;    //Encode    av_init_packet(&pkt);    pkt.data = NULL;    // packet data will be allocated by the encoder    pkt.size = 0;    //YUV这样去是正确的;    //Y    pFrame->data[0] = yuv420p;    //U    pFrame->data[1] = yuv420p + y_size;    //V    pFrame->data[2] = yuv420p + y_size * 5 / 4;    //pts和dts;    pFrame->pts = index;    //int64_t类型的打印方式有所不同;    LOGI("pts %"                 PRId64                 "\n", pFrame->pts);    /* encode the image */    ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);    if (ret < 0) {        LOGI("Error encoding frame!");    }    //没有用到;    if (got_output) {        LOGI("Succeed to encode frame size:%5d!", pkt.size);        h264 = (*env)->NewByteArray(env, pkt.size);        (*env)->SetByteArrayRegion(env, h264, 0, pkt.size, pkt.data);        av_free_packet(&pkt);    }    //Flush Encoder    for (got_output = 1; got_output; i++) {        ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output);        if (ret < 0) {            LOGI("Error encoding frame!");        }        if (got_output) {            LOGI("Flush Encoder: Succeed to encode 1 frame!  size:%5d", pkt.size);            h264 = (*env)->NewByteArray(env, pkt.size);            (*env)->SetByteArrayRegion(env, h264, 0, pkt.size, pkt.data);            av_free_packet(&pkt);        }    }    avcodec_close(pCodecCtx);    av_free(pCodecCtx);    av_frame_free(&pFrame);    (*env)->ReleaseByteArrayElements(env, yuv420p_, yuv420p, 0);    return h264;}

文件

JNIEXPORT jbyteArray JNICALLJava_com_uestc_smileteeth_view_recordvideo_RecordVideoLib_encodeVideoFrame(JNIEnv *env, jclass type,                                                                           jstring path1_,                                                                           jstring path2_,                                                                           jint frameNum,                                                                           jint width, jint height,                                                                           jintArray pts_) {    const char *path1 = (*env)->GetStringUTFChars(env, path1_, 0);    const char *path2 = (*env)->GetStringUTFChars(env, path2_, 0);    jint *pts = (*env)->GetIntArrayElements(env, pts_, NULL);    AVFormatContext *pFormatCtx;    AVOutputFormat *fmt;    AVStream *video_st;    AVCodecContext *pCodecCtx;    AVCodec *pCodec;    AVPacket pkt;    uint8_t *picture_buf;    AVFrame *pFrame;    int picture_size;    int y_size;    int framecnt = 0;    //FILE *in_file = fopen("src01_480x272.yuv", "rb"); //Input raw YUV data    FILE *in_file = fopen(path1, "rb");   //Input raw YUV data    int in_w = width, in_h = height;                              //Input data's width and height    //总帧数;    int framenum = frameNum;                                   //Frames to encode    //输出路径;    const char *out_file = path2;    av_register_all();    //Method1.    pFormatCtx = avformat_alloc_context();    //Guess Format    fmt = av_guess_format(NULL, out_file, NULL);    pFormatCtx->oformat = fmt;    //Method 2.    //avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);    //fmt = pFormatCtx->oformat;    //Open output URL    if (avio_open(&pFormatCtx->pb, out_file, AVIO_FLAG_READ_WRITE) < 0) {        LOGI("Failed to open output file! ");    }    video_st = avformat_new_stream(pFormatCtx, 0);    //video_st->time_base.num = 1;    //video_st->time_base.den = 25;    if (video_st == NULL) {    }    //Param that must set    pCodecCtx = video_st->codec;    //pCodecCtx->codec_id =AV_CODEC_ID_HEVC;    pCodecCtx->codec_id = fmt->video_codec;    pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;    pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;    pCodecCtx->width = in_w;    pCodecCtx->height = in_h;    pCodecCtx->bit_rate = 30000000;    pCodecCtx->gop_size = 5;    pCodecCtx->time_base.num = 1;    pCodecCtx->time_base.den = 25;    //H264    pCodecCtx->me_range = 32;    //pCodecCtx->max_qdiff = 4;    //pCodecCtx->qcompress = 0.6;    pCodecCtx->qmin = 10;    pCodecCtx->qmax = 40;    //Optional Param    pCodecCtx->max_b_frames = 0;    // Set Option    AVDictionary *param = 0;    //H.264    if (pCodecCtx->codec_id == AV_CODEC_ID_H264) {        av_dict_set(¶m, "preset", "slow", 0);        av_dict_set(¶m, "tune", "zerolatency", 0);        //av_dict_set(¶m, "profile", "main", 0);    }    //H.265    if (pCodecCtx->codec_id == AV_CODEC_ID_H265) {        av_dict_set(¶m, "preset", "ultrafast", 0);        av_dict_set(¶m, "tune", "zero-latency", 0);    }    //Show some Information    av_dump_format(pFormatCtx, 0, out_file, 1);    pCodec = avcodec_find_encoder(pCodecCtx->codec_id);    if (!pCodec) {        LOGI("Can not find encoder! ");    }    if (avcodec_open2(pCodecCtx, pCodec, ¶m) < 0) {        LOGI("Failed to open encoder! ");    }    pFrame = av_frame_alloc();    picture_size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);    picture_buf = (uint8_t *) av_malloc(picture_size);    avpicture_fill((AVPicture *) pFrame, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width,                   pCodecCtx->height);    //Write File Header    avformat_write_header(pFormatCtx, NULL);    av_new_packet(&pkt, picture_size);    y_size = pCodecCtx->width * pCodecCtx->height;    for (int i = 0; i < framenum; i++) {        LOGI("完整视频正在编码第%d帧", i + 1);        //Read raw YUV data        if (fread(picture_buf, 1, y_size * 3 / 2, in_file) <= 0) {            LOGI("Failed to read raw data! ");        } else if (feof(in_file)) {            break;        }        pFrame->data[0] = picture_buf;              // Y        pFrame->data[1] = picture_buf + y_size;      // U        pFrame->data[2] = picture_buf + y_size * 5 / 4;  // V        //PTS        pFrame->pts = pts[i];        LOGI("pts %"                     PRId64                     "\n", pFrame->pts);        int got_picture = 0;        //Encode        int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_picture);        if (ret < 0) {            LOGI("Failed to encode! ");        }        if (got_picture == 1) {            framecnt++;            LOGI("Succeed to encode frame: %5d\tsize:%5d", framecnt, pkt.size);            pkt.stream_index = video_st->index;            ret = av_write_frame(pFormatCtx, &pkt);            av_free_packet(&pkt);        }    }    //Flush Encoder    int ret = flush_encoder(pFormatCtx, 0);    if (ret < 0) {        LOGI("Flushing encoder failed!");    }    //Write file trailer    av_write_trailer(pFormatCtx);    //Clean    if (video_st) {        avcodec_close(video_st->codec);        av_free(pFrame);        av_free(picture_buf);    }    avio_close(pFormatCtx->pb);    avformat_free_context(pFormatCtx);    fclose(in_file);    (*env)->ReleaseStringUTFChars(env, path1_, path1);    (*env)->ReleaseStringUTFChars(env, path2_, path2);    (*env)->ReleaseIntArrayElements(env, pts_, pts, 0);}int flush_encoder(AVFormatContext *fmt_ctx, unsigned int stream_index) {    int ret;    int got_frame;    AVPacket enc_pkt;    if (!(fmt_ctx->streams[stream_index]->codec->codec->capabilities &          CODEC_CAP_DELAY))        return 0;    while (1) {        enc_pkt.data = NULL;        enc_pkt.size = 0;        av_init_packet(&enc_pkt);        ret = avcodec_encode_video2(fmt_ctx->streams[stream_index]->codec, &enc_pkt,                                    NULL, &got_frame);        av_frame_free(NULL);        if (ret < 0)            break;        if (!got_frame) {            ret = 0;            break;        }        LOGI("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d", enc_pkt.size);        /* mux encoded frame */        ret = av_write_frame(fmt_ctx, &enc_pkt);        if (ret < 0)            break;    }    return ret;}

推荐
雷神的FFMPEG专栏

更多相关文章

  1. android 根据SD卡中图片路径读取并显示SD中的图片――源代码
  2. android读取SDCard任意路径下的文件
  3. Android之adt 23找不到NDK路径设置解决方案
  4. Android 模拟器中AVD路径的修改
  5. Android各版本 内外卡真实路径
  6. AVD(android virtual device)路径设置
  7. APK安装路径移动至外部存储设备
  8. android实现图片按任意路径截取
  9. Android下载文件保存到路径

随机推荐

  1. Android 分页组件
  2. android反编译与加固(Mac版)
  3. Android常见布局简述
  4. Android中文文档v0.1 beta低调发布,期待
  5. Android可收缩/扩展的TextView【2】
  6. 《宅男的android开发指南》(翻译)--1
  7. android ViewPager不可滑动(android 项目
  8. Android(安卓)适配不同分辨率&hdpi、mdpi
  9. Android 2.2 开发环境配置详解
  10. 【 Android 】Android Runtime Permissio