JNIEXPORT jbyteArray JNICALLJava_com_uestc_smileteeth_view_recordvideo_RecordVideoLib_decodeVideo(JNIEnv *env, jclass type,                                                                      jstring input_,                                                                      jstring output_) {    const char *input = (*env)->GetStringUTFChars(env, input_, 0);    const char *output = (*env)->GetStringUTFChars(env, output_, 0);    AVFormatContext *pFormatCtx;    int i, videoindex;    AVCodecContext *pCodecCtx;    AVCodec *pCodec;    AVFrame *pFrame, *pFrameYUV;    uint8_t *out_buffer;    AVPacket *packet;    int y_size;    int ret, got_picture;    struct SwsContext *img_convert_ctx;    FILE *fp_yuv;    int frame_cnt;    clock_t time_start, time_finish;    double time_duration = 0.0;    char info[1000] = {0};    av_register_all();    avformat_network_init();    pFormatCtx = avformat_alloc_context();    if (avformat_open_input(&pFormatCtx, input, NULL, NULL) != 0) {        LOGI("Couldn't open input stream.\n");        return -1;    }    if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {        LOGI("Couldn't find stream information.\n");        return -1;    }    videoindex = -1;    for (i = 0; i < pFormatCtx->nb_streams; i++)        if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {            videoindex = i;            break;        }    if (videoindex == -1) {        LOGI("Couldn't find a video stream.\n");        return -1;    }    pCodecCtx = pFormatCtx->streams[videoindex]->codec;    pCodec = avcodec_find_decoder(pCodecCtx->codec_id);    if (pCodec == NULL) {        LOGI("Couldn't find Codec.\n");        return -1;    }    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {        LOGI("Couldn't open codec.\n");        return -1;    }    pFrame = av_frame_alloc();    pFrameYUV = av_frame_alloc();    out_buffer = (unsigned char *) av_malloc(            av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1));    av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, out_buffer,                         AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);    packet = (AVPacket *) av_malloc(sizeof(AVPacket));    img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,                                     pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P,                                     SWS_BICUBIC, NULL, NULL, NULL);    sprintf(info, "[Input     ]%s\n", input);    sprintf(info, "%s[Output    ]%s\n", info, output);    sprintf(info, "%s[Format    ]%s\n", info, pFormatCtx->iformat->name);    sprintf(info, "%s[Codec     ]%s\n", info, pCodecCtx->codec->name);    sprintf(info, "%s[Resolution]%dx%d\n", info, pCodecCtx->width, pCodecCtx->height);    fp_yuv = fopen(output, "wb+");    if (fp_yuv == NULL) {        printf("Cannot open output file.\n");        return -1;    }    frame_cnt = 0;    time_start = clock();    while (av_read_frame(pFormatCtx, packet) >= 0) {        if (packet->stream_index == videoindex) {            ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);            if (ret < 0) {                LOGI("Decode Error.\n");                return -1;            }            if (got_picture) {                sws_scale(img_convert_ctx, (const uint8_t *const *) pFrame->data, pFrame->linesize,                          0, pCodecCtx->height,                          pFrameYUV->data, pFrameYUV->linesize);                y_size = pCodecCtx->width * pCodecCtx->height;                fwrite(pFrameYUV->data[0], 1, y_size, fp_yuv);    //Y                fwrite(pFrameYUV->data[1], 1, y_size / 4, fp_yuv);  //U                fwrite(pFrameYUV->data[2], 1, y_size / 4, fp_yuv);  //V                //Output info                char pictype_str[10] = {0};                switch (pFrame->pict_type) {                    case AV_PICTURE_TYPE_I:                        sprintf(pictype_str, "I");                        break;                    case AV_PICTURE_TYPE_P:                        sprintf(pictype_str, "P");                        break;                    case AV_PICTURE_TYPE_B:                        sprintf(pictype_str, "B");                        break;                    default:                        sprintf(pictype_str, "Other");                        break;                }                LOGI("Frame Index: %5d. Type:%s", frame_cnt, pictype_str);                frame_cnt++;            }        }        av_free_packet(packet);    }    //flush decoder    //FIX: Flush Frames remained in Codec    while (1) {        ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);        if (ret < 0)            break;        if (!got_picture)            break;        sws_scale(img_convert_ctx, (const uint8_t *const *) pFrame->data, pFrame->linesize, 0,                  pCodecCtx->height,                  pFrameYUV->data, pFrameYUV->linesize);        int y_size = pCodecCtx->width * pCodecCtx->height;        fwrite(pFrameYUV->data[0], 1, y_size, fp_yuv);    //Y        fwrite(pFrameYUV->data[1], 1, y_size / 4, fp_yuv);  //U        fwrite(pFrameYUV->data[2], 1, y_size / 4, fp_yuv);  //V        //Output info        char pictype_str[10] = {0};        switch (pFrame->pict_type) {            case AV_PICTURE_TYPE_I:                sprintf(pictype_str, "I");                break;            case AV_PICTURE_TYPE_P:                sprintf(pictype_str, "P");                break;            case AV_PICTURE_TYPE_B:                sprintf(pictype_str, "B");                break;            default:                sprintf(pictype_str, "Other");                break;        }        LOGI("Frame Index: %5d. Type:%s", frame_cnt, pictype_str);        frame_cnt++;    }    time_finish = clock();    time_duration = (double) (time_finish - time_start);    sprintf(info, "%s[Time      ]%fms\n", info, time_duration);    sprintf(info, "%s[Count     ]%d\n", info, frame_cnt);    sws_freeContext(img_convert_ctx);    fclose(fp_yuv);    av_frame_free(&pFrameYUV);    av_frame_free(&pFrame);    avcodec_close(pCodecCtx);    avformat_close_input(&pFormatCtx);    (*env)->ReleaseStringUTFChars(env, input_, input);    (*env)->ReleaseStringUTFChars(env, output_, output);    return 0;}

推荐
雷神的FFMPEG专栏

更多相关文章

  1. 一些优秀的 Android 开发专栏推荐
  2. Android 专栏整理
  3. android contentprovider学习(遇到最满意的介绍)---阿冬专栏
  4. Android Gradle Plugin指南(一)——简介 - 琴弦第七的专栏 - 博客
  5. Android中文资源站专栏:五个好用的日常软件
  6. 专家专栏:Android层次化安全架构及核心组件概览
  7. 没有这样的专栏:blog_article.date
  8. 教你如何秒杀12306,JAVA程序抢票成功!----阿冬专栏

随机推荐

  1. Android(安卓)ScrollView 去掉 scrollbar
  2. Android(安卓)API等级、Android版本、发
  3. PULL解析XML
  4. Android(安卓)应用Crash 后自动重启
  5. Android文件列表RecyclerView中点击视频
  6. Android禁止下拉状态栏
  7. Android(安卓)之应用程序重启
  8. Android(安卓)9.0 P 状态栏下移的实现
  9. Android(安卓)复习笔记之图解Intent和Int
  10. AnimatedStateListDrawable介绍