简体   繁体   中英

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. 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 ? Then you need to get these details from your AVFormatContext . AVPacket has stream_index and you can use that to get details of the stream that the packet represents. The other useful info is the pts/dts and size of the packet.

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::streams are the streams that are part of your media file (eg audio, video). This way from each AVPacket you can get AVStream that the packet represents. In AVStream you can inspect codec , duration of the stream and other useful parameters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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