Как читать данные, используя ffmpeg в C? - PullRequest
0 голосов
/ 24 октября 2018

Я следовал этому руководству: http://dranger.com/ffmpeg/tutorial01.html для использования ffmpeg в Android Studio с использованием Android NDK.Я сделал небольшое исправление, так как некоторые функции, используемые здесь, сейчас устарели. Вот мой код, кто угодно может указать, что не так с моим кодом, так как я получаю сообщение об ошибке, и не могу выяснить, что не так

#include <jni.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame);
JNICALL
JNIEXPORT jstring
Java_com_viralsam_root_tester_MainActivity_trtest(JNIEnv *env, jobject obj , jint argc,
                                                  jstring argv_){
    const char *name;
    int i,videostream;
    name= (*env)->GetStringUTFChars(env, argv_,0);
    AVFormatContext *pFormatctx=NULL;
    if (avformat_open_input(&pFormatctx,name,NULL,NULL)!=0){
        return (*env)->NewStringUTF(env,"a");
    }
    if(pFormatctx==NULL){
        return (*env)->NewStringUTF(env,"b");
    }
    if(avformat_find_stream_info(pFormatctx,NULL)<0){
        return (*env)->NewStringUTF(env,"c");
    }
    av_dump_format(pFormatctx, 0, name, 0);
    videostream=-1;
    AVCodecContext *pCodecCtxOrig = NULL;
    AVCodecContext *pCodecCtx = NULL;
    for (i=0;i<pFormatctx->nb_streams;i++){
        if((pFormatctx->streams[i]->codecpar->codec_type)==AVMEDIA_TYPE_VIDEO){
            videostream=i;
            break;
        }
    }
    if(videostream==-1){
        return (*env)->NewStringUTF(env,"d");
    }
    pCodecCtx=pFormatctx->streams[videostream]->codecpar;
    AVCodec *pCodec = NULL;
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec==NULL){
        return (*env)->NewStringUTF(env,"e");
    }
    pCodecCtx=avcodec_alloc_context3(pCodec);
    if(avcodec_open2(pCodecCtx,pCodec,NULL)<0){
        return (*env)->NewStringUTF(env,"g");
    }
    AVFrame *pFrame = NULL,*pFrameRBG=NULL;

    pFrame=av_frame_alloc();
    pFrameRBG=av_frame_alloc();
    if(pFrameRBG==NULL){
        return (*env)->NewStringUTF(env,"h");
    }
    uint8_t *buffer=NULL;
    int numBytes;
    numBytes=av_image_get_buffer_size(AV_PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height,1);
    buffer=(uint8_t *)av_malloc(numBytes* sizeof(uint8_t));
    av_image_fill_arrays(pFrameRBG->data,pFrameRBG->linesize,buffer,AV_PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height,1);
    struct SwsContext *sws_ctx = NULL;
    int frameFinished;
    AVPacket *packet=av_packet_alloc();
    sws_ctx=sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,AV_PIX_FMT_RGB24,SWS_BILINEAR,NULL,NULL,NULL);
    i=0;
    while(av_read_frame(pFormatctx,&packet)>=0){

        if(packet->stream_index==videostream){
            int used=avcodec_send_packet(pCodecCtx,&packet);
            used=avcodec_receive_frame(pCodecCtx,pFrame);
            if (used < 0 && used != AVERROR(EAGAIN) && used != AVERROR_EOF){
                break;

            } else{

                if (used == AVERROR(EAGAIN) || used == AVERROR_EOF){
                    break;
                }
            }

            sws_scale(sws_ctx,(uint8_t const * const *)pFrame->data,pFrame->linesize,0,pCodecCtx->height,pFrameRBG->data,pFrameRBG->linesize);
            if(++i<=5){
                SaveFrame(pFrameRBG,pCodecCtx->width,pCodecCtx->height,i);
            }


        }
        av_packet_free(&packet);

    }
    char blubuk[50];
    sprintf(blubuk,"%d",buffer);
    av_free(buffer);
    av_frame_free(&pFrameRBG);
    av_frame_free(&pFrame);
    avcodec_close(pCodecCtx);
    avcodec_close(pCodecCtxOrig);
    avformat_close_input(&pFormatctx);

    return (*env)->NewStringUTF(env,blubuk);

}
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame){
    FILE *pFile;
    char szFilename[32];
    int  y;
    sprintf(szFilename, "frame%d.ppm", iFrame);
    pFile=fopen(szFilename,"wb");
    if(pFile==NULL){
        return;
    }
    fprintf(pFile, "P6\n%d %d\n255\n", width, height);
    for(y=0; y<height; y++){
        fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
    }
    fclose(pFile);

}

ОБНОВЛЕНИЕ:Я получаю "-22" от "int used = avcodec_send_packet (pCodecCtx, package);". Не могу понять, где я ошибся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...