2017-10-07 129 views
1

我花了數小時試圖解決這個問題:FFmpeg api iOS「資源暫時不可用」

我想在iOS上使用ffmpeg api。我的Xcode項目正在構建中,我可以調用ffmpeg api函數。我試圖編寫解碼視頻的代碼(現在不輸出任何內容),並且我一直收到錯誤-35:「資源暫時不可用」。

輸入文件來自相機膠捲(.mov),我使用Mpeg-4進行解碼。我目前所做的只是從文件中獲取數據,解析數據並將解析的數據包發送給解碼器。當我嘗試獲取框架時,我得到的只是一個錯誤。有誰知道我做錯了什麼?

+(void)test: (NSString*)filename outfile:(NSString*)outfilename { 

/* register all the codecs */ 
avcodec_register_all(); 

AVCodec *codec; 
AVCodecParserContext *parser; 
AVCodecContext *c= NULL; 
int frame_count; 
FILE* f; 
AVFrame* frame; 
AVPacket* avpkt; 
avpkt = av_packet_alloc(); 
//av_init_packet(avpkt); 
char buf[1024]; 

uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; 
uint8_t *data; 
size_t data_size; 

/* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ 
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE); 

printf("Decode video file %s to %s\n", [filename cStringUsingEncoding:NSUTF8StringEncoding], [outfilename cStringUsingEncoding:NSUTF8StringEncoding]); 
/* find the h264 video decoder */ 
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG4); 
if (!codec) { 
    fprintf(stderr, "Codec not found\n"); 
    exit(1); 
} 
c = avcodec_alloc_context3(codec); 
if (!c) { 
    fprintf(stderr, "Could not allocate video codec context\n"); 
    exit(1); 
} 
if (codec->capabilities & AV_CODEC_CAP_TRUNCATED) 
    c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames 
/* For some codecs, such as msmpeg4 and mpeg4, width and height 
MUST be initialized there because this information is not 
available in the bitstream. */ 
/* open it */ 
if (avcodec_open2(c, codec, NULL) < 0) { 
    fprintf(stderr, "Could not open codec\n"); 
    exit(1); 
} 
f = fopen([filename cStringUsingEncoding:NSUTF8StringEncoding], "rb"); 
if (!f) { 
    fprintf(stderr, "Could not open %s\n", [filename cStringUsingEncoding:NSUTF8StringEncoding]); 
    exit(1); 
} 
frame = av_frame_alloc(); 
if (!frame) { 
    fprintf(stderr, "Could not allocate video frame\n"); 
    exit(1); 
} 
frame_count = 0; 

parser = av_parser_init(codec->id); 
if (!parser) { 
    fprintf(stderr, "parser not found\n"); 
    exit(1); 
} 

while (!feof(f)) { 
    /* read raw data from the input file */ 
    data_size = fread(inbuf, 1, INBUF_SIZE, f); 
    if (!data_size) 
     break; 
    /* use the parser to split the data into frames */ 
    data = inbuf; 
    while (data_size > 0) { 
     int ret = av_parser_parse2(parser, c, &avpkt->data, &avpkt->size, data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0); 
     if (ret < 0) { 
      fprintf(stderr, "Error while parsing\n"); 
      exit(1); 
     } 
     data  += ret; 
     data_size -= ret; 
     if (avpkt->size){ 
      char buf[1024]; 

      ret = avcodec_send_packet(c, avpkt); 
      if (ret < 0) { 

       fprintf(stderr, "Error sending a packet for decoding\n"); 
       continue; 
       exit(1); 
      } 

      while (ret >= 0) { 
       ret = avcodec_receive_frame(c, frame); 
       if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){ 
        char e [1024]; 
        av_strerror(ret, e, 1024); 
        fprintf(stderr, "Fail: %s !\n", e); 
// ~~~~~~~~ This is where my program exits ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
        return; 
       } 
       else if (ret < 0) { 
        fprintf(stderr, "Error during decoding\n"); 
        exit(1); 
       } 
      } 


     } 
    } 
} 
/* some codecs, such as MPEG, transmit the I and P frame with a 
latency of one frame. You must do the following to have a 
chance to get the last frame of the video */ 

fclose(f); 
avcodec_close(c); 
av_free(c); 
av_frame_free(&frame); 
printf("\n"); 

}

回答

3

AVERROR(EAGAIN)是不是一個錯誤,它只是意味着輸出還不可用,你需要調用_send_packet()第一輸出前幾次將可從_receive_frame()

輸出被緩衝(延遲)以允許B幀和幀線程。

相關問題