简体   繁体   English

如何使用FFMPEG从编码视频中提取AVPacket的重要信息

[英]How to extract important information of an AVPacket from an encoded video using FFMPEG

I wrote a code to read a video in encoded domain and able to retrieve information such as size and duration of frames. 我编写了一个代码来读取编码域中的视频,并且能够检索诸如帧的大小和持续时间之类的信息。 AVPacket class consist of a variable as data. AVPacket类包含一个作为数据的变量。 I can read it but since it is a bite array I can't use it in readable format. 我可以读取它,但是由于它是一个咬合数组,因此我无法以可读格式使用它。 I want to use this data for comparison with another video file. 我想将此数据与另一个视频文件进行比较。 Please help. 请帮忙。

void CFfmpegmethods::VideoRead(){
av_register_all();
avformat_network_init();
ofstream outdata;
const char *url = "H:\\Sanduni_projects\\Sample_video.mp4";
AVDictionary *options = NULL;
AVFormatContext *s = avformat_alloc_context(); //NULL;

AVPacket *pkt = new AVPacket();

//open an input stream and read the header
int ret = avformat_open_input(&s, url, NULL, NULL);

//avformat_find_stream_info(s, &options); //finding the missing information 

if (ret < 0)
    abort();

av_dict_set(&options, "video_size", "640x480", 0);
av_dict_set(&options, "pixel_format", "rgb24", 0);

if (avformat_open_input(&s, url, NULL, &options) < 0){
    abort();
}

av_dict_free(&options);

AVDictionaryEntry *e;

if (e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX)) {
    fprintf(stderr, "Option %s not recognized by the demuxer.\n", e->key);
    abort();
}

int i = 1;
int j = 0;
int64_t duration = 0;
int size = 0;
uint8_t *data = 0; //Unsigned integer type with a width of exactly 8 bits.
int sum = 0;

int total_size = 0;
int total_duration = 0;
int packet_size = 0;
int64_t stream_index = 0;
int64_t bit_rate = 0;

//writing data to a file
outdata.open("H:\\Sanduni_projects\\log.txt");

if (!outdata){
    cerr << "Error: file could not be opened" << endl;
    exit(1);
}

//Split what is stored in the file into frames and return one for each call
//returns the next frame of the stream

while(1){
    int frame = av_read_frame(s, pkt);
    if (frame < 0) break;

    duration = pkt->duration;
    size = pkt->size;

    total_size = total_size + size;
    total_duration = total_duration + duration;

    cout << "frame:" << i << " " << size << " " << duration << endl;
    data = pkt->data;
    outdata << "Frame: " << i << " ";
    outdata << data<< endl;

    for (j = 0; j < size; j++){

    }

    i++;
    //pkt_no++;
    //outdata << sum << endl;       
}

//make the packet free
av_packet_unref(pkt);
delete pkt;

cout << "total size: " << total_size << endl;
cout << "total duration:" << total_duration << endl;

outdata.close();

//Close the file after reading
avformat_close_input(&s);

} }

I can't use it in readable format 我无法以可读格式使用它

Why do you want that? 你为什么要那样? You want to output details of you AVPAcket ? 您要输出AVPAcket的详细信息吗? Then you need to get these details from your AVFormatContext . 然后,您需要从AVFormatContext获取这些详细信息。 AVPacket has stream_index and you can use that to get details of the stream that the packet represents. AVPacket具有stream_index ,您可以使用它来获取数据包表示的流的详细信息。 The other useful info is the pts/dts and size of the packet. 其他有用的信息是数据包的pts / dts和大小。

AVPacket pkt = ...;
AVFormatContext *s = ... ;

AVStream* stream = s->streams[pkt.stream_index]; // get the stream

Basically each media file contains multiple streams. 基本上每个媒体文件都包含多个流。 When you open a file AVFormatContext stores information about the file that you open. 当您打开文件时, AVFormatContext存储有关您打开的文件的信息。 AVFormatContext::streams are the streams that are part of your media file (eg audio, video). AVFormatContext::streams是媒体文件(例如,音频,视频)一部分的流。 This way from each AVPacket you can get AVStream that the packet represents. 通过这种方式,您可以从每个AVPacket中获取数据包所代表的AVStream In AVStream you can inspect codec , duration of the stream and other useful parameters. AVStream您可以检查codec ,流的duration和其他有用的参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM