1

avi file with h264 codec. I need to open it and extract the timestamp of every frame.

I tried to do it in opencv but it returns wrong results.

I have modified the code of the example filtering_video.c that exists in the fffmpeg/doc/examples folder in order to get the timestamp.

I have the following code but compiling it gives me a strange result about UNIT64_C. Searching around I saw that it is a ffmpeg problem.

So 2 questions: 1. Does this code look capable of returning and printing the frame timestamp 2. any solution to the UINT64_C problem??

Using ubuntu 11.04 and latest ffmpeg.

code

#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);
}

compiler errors

/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|
manlio
  • 18,345
  • 14
  • 76
  • 126
jmlaios
  • 119
  • 3
  • 11

3 Answers3

2

UINT64_C is declared in <stdint.h> so include that before any other headers and it shouldn't complain about that anymore.

Alan Curry
  • 14,255
  • 3
  • 32
  • 33
  • linked it first but compliler still gets angry about UINT64_C. also linked inttypes.h but still. – jmlaios Jul 31 '12 at 16:08
  • Show `gcc -E -dD -C yourfile.c | grep UINT64_C` after adding the `stdint` and `inttypes` includes – Alan Curry Jul 31 '12 at 16:54
  • `#define __UINT64_C(c) c ## UL #define __UINT64_C(c) c ## UL #define UINT64_MAX (__UINT64_C(18446744073709551615)) #define UINT_LEAST64_MAX (__UINT64_C(18446744073709551615)) #define UINT_FAST64_MAX (__UINT64_C(18446744073709551615)) #define UINTMAX_MAX (__UINT64_C(18446744073709551615)) #define UINT64_C(c) c ## UL ` what does it mean? – jmlaios Aug 01 '12 at 09:43
  • Looks like a correct definition of `UINT64_C` to me. I don't know why the compiler wouldn't like it. – Alan Curry Aug 01 '12 at 15:31
0

The definition of UINT64_C is inside a condition:

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

Looks like if you're using ffmpeg from C++98 as I am, you'll need to

#define __STDC_CONSTANT_MACROS

before you

#include <stdint.h>
Devin Lane
  • 964
  • 1
  • 7
  • 14
0

I found that stdint.h defines the macro INT64_C only for C, but not for C++. Since I didn't want to hassle too much with the headers of ffmpeg, I placed this definition in my code, above all the includes from ffmpeg

#ifndef INT64_C
#define INT64_C(c) (c ## LL)
#define UINT64_C(c) (c ## ULL)
#endif
Haggai
  • 458
  • 1
  • 5
  • 13