2012-07-29 96 views
1

帶h264編解碼器的avi文件。我需要打開它並提取每個幀的時間戳。ffmpeg H264 avi文件獲取幀時間戳UINT64_C錯誤

我試圖在opencv中做它,但它返回錯誤的結果。

我已經修改了fffmpeg/doc/examples文件夾中存在的示例filtering_video.c的代碼,以獲取時間戳。

我有下面的代碼,但編譯它給了我一個關於UNIT64_C的奇怪結果。 搜索我看到它是一個ffmpeg問題。

So 2 questions: 1.此代碼是否能夠返回並打印幀時間戳 2.對UINT64_C問題的任何解決方案?

使用ubuntu 11.04和最新的ffmpeg。

代碼

#include <unistd.h> 

#include <libavcodec/avcodec.h> 
#include <libavformat/avformat.h> 

static AVFormatContext *fmt_ctx; 
static AVCodecContext *dec_ctx; 
static int video_stream_index = -1; 

static int open_input_file(const char *filename) 
{ 
int ret; 
AVCodec *dec; 

if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) 
{ 
    printf("Cannot open input file\n"); 
    return ret; 
} 

if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) 
{ 
    printf("Cannot find stream information\n"); 
    return ret; 
} 

/* select the video stream */ 
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0); 
if (ret < 0) 
{ 
    printf("Cannot find a video stream in the input file\n"); 
    return ret; 
} 
video_stream_index = ret; 
dec_ctx = fmt_ctx->streams[video_stream_index]->codec; 

/* init the video decoder */ 
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) 
{ 
    printf("Cannot open video decoder\n"); 
    return ret; 
} 

return 0; 
} 

int main(int argc, char **argv) 
{ 
int ret; 
AVPacket packet; 
AVFrame frame; 
int got_frame; 

if (argc != 2) 
{ 
    fprintf(stderr, "Usage: %s file\n", argv[0]); 
    exit(1); 
} 

avcodec_register_all(); 
av_register_all(); 

if ((ret = open_input_file(argv[1])) < 0) 
    goto end; 

/* read all packets */ 
while (1) 
{ 
    if ((ret = av_read_frame(fmt_ctx, &packet)) < 0) 
     break; 

    if (packet.stream_index == video_stream_index) 
    { 
     avcodec_get_frame_defaults(&frame); 
     got_frame = 0; 
     ret = avcodec_decode_video2(dec_ctx, &frame, &got_frame, &packet); 
     if (ret < 0) 
     { 
      printf("Error decoding video\n"); 
      break; 
     } 

     if (got_frame) 
     { 
      frame.pts = av_frame_get_best_effort_timestamp(&frame); 
      printf("frame timestamp %ld\n", frame.pts); 
     } 

    } 
} 
    av_free_packet(&packet); 
end: 
if (dec_ctx) 
    avcodec_close(dec_ctx); 
avformat_close_input(&fmt_ctx); 

exit(0); 
} 

編譯器錯誤

/usr/local/include/libavutil/common.h||In function ‘int32_t av_clipl_int32_c(int64_t)’:| 
/usr/local/include/libavutil/common.h|173|error: ‘UINT64_C’ was not declared in this scope| 

回答

2

UINT64_C<stdint.h>宣佈這樣包括之前的任何其他頭,它不應該抱怨這個問題了。

+0

第一個鏈接,但仍然compliler生氣關於UINT64_C全部包括。也鏈接inttypes.h但仍然。 – jmlaios 2012-07-31 16:08:14

+0

顯示'gcc -E -dD -C yourfile.c |的grep UINT64_C'加入'stdint'和'inttypes'包括 – 2012-07-31 16:54:23

+0

'的#define __UINT64_C(C)C## UL 的#define __UINT64_C(C)C## UL 的#define UINT64_MAX(__UINT64_C(18446744073709551615)) #定義後UINT_LEAST64_MAX(__UINT64_C(18446744073709551615)) 的#define UINT_FAST64_MAX(__UINT64_C(18446744073709551615)) 的#define UINTMAX_MAX(__UINT64_C(18446744073709551615)) 的#define UINT64_C(三)C## UL '是什麼意思? – jmlaios 2012-08-01 09:43:13

0

UINT64_C的定義是一個狀態裏面:

/* The ISO C99 standard specifies that in C++ implementations these 
    should only be defined if explicitly requested. */ 
#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS 

看起來如果你使用的C++ 98的ffmpeg,因爲我,你需要

#define __STDC_CONSTANT_MACROS 

前你

#include <stdint.h> 
0

我發現stdint.h定義宏INT64_C只爲C,而不是C++。 因爲我不想費盡口舌太多有關ffmpeg的頭,我把我的代碼這個定義,從上面的ffmpeg

#ifndef INT64_C 
#define INT64_C(c) (C## LL) 
#define UINT64_C(c) (C## ULL) 
#endif