Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <libavcodec/avcodec.h>
- #include <libavformat/avformat.h>
- #include <libavutil/avconfig.h>
- #include <libswscale/swscale.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
- #include <inttypes.h>
- typedef struct SwsContext SwsContext;
- static void save_gray_frame(unsigned char *buf, int wrap, int xsize, int ysize, char *filename)
- {
- FILE *f;
- int i;
- f = fopen(filename,"w");
- // writing the minimal required header for a pgm file format
- // portable graymap format -> https://en.wikipedia.org/wiki/Netpbm_format#PGM_example
- fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
- // writing line by line
- for (i = 0; i < ysize; i++)
- fwrite(buf + i * wrap, 1, xsize, f);
- fclose(f);
- }
- int main() {
- AVFormatContext* ctx = avformat_alloc_context();
- if (!ctx) {
- puts("couldn't allocate the context\n");
- return -1;
- }
- int res = avformat_open_input(&ctx, "demo.mp4", NULL, NULL);
- if (res < 0) {
- puts("couldn't open the media file\n");
- return -1;
- }
- printf("Format: %s\n", ctx->iformat->name);
- printf("Format long: %s\n", ctx->iformat->long_name);
- printf("Format MIME type: %s\n", ctx->iformat->mime_type);
- printf("Duration: %lld\n", ctx->duration);
- printf("Bitrate: %lld\n", ctx->bit_rate == 0 ? -1 : ctx->bit_rate);
- printf("Number of streams: %d\n", ctx->nb_streams);
- res = avformat_find_stream_info(ctx, NULL);
- if (res < 0) {
- puts("couldn't find stream info\n");
- return -1;
- }
- putc('\n', stdout);
- AVCodec* videoCodec = NULL;
- AVCodecParameters* videoCodecParams = NULL;
- int videoStreamInd = -1;
- // Loop through all the streams.
- for (int i = 0; i < ctx->nb_streams; i++) {
- AVStream* stream = ctx->streams[i];
- AVCodecParameters* codecParams = stream->codecpar;
- switch (codecParams->codec_type)
- {
- case AVMEDIA_TYPE_VIDEO:
- puts("Type: video");
- printf("Resolution: %dx%d\n", codecParams->width, codecParams->height);
- break;
- case AVMEDIA_TYPE_AUDIO:
- puts("Type: audio");
- printf("Number of channels: %d\n", codecParams->channels);
- printf("Sample rate: %d\n", codecParams->sample_rate);
- printf("Frame size: %d\n", codecParams->frame_size);
- break;
- default:
- printf("unsupported stream type: %d\n", codecParams->codec_type);
- return -1;
- }
- printf("Stream %d index: %d\n", i, stream->index);
- printf("Stream %d time base before opened: %d/%d\n", i, stream->time_base.num, stream->time_base.den);
- printf("Stream %d frame rate before opened: %d/%d\n", i, stream->r_frame_rate.num, stream->r_frame_rate.den);
- printf("Stream %d start time: %d\n", i, stream->start_time);
- printf("Stream %d duration: %d\n", i, stream->duration);
- printf("Stream %d number of frames: %d\n", i, stream->nb_frames);
- printf("Stream %d bit rate: %d\n", i, codecParams->bit_rate);
- AVCodec* codec = avcodec_find_decoder(codecParams->codec_id);
- if (codec == NULL) {
- printf("couldn't find the codec with ID = %d", codecParams->codec_id);
- return -1;
- }
- printf("Stream %d codec name: %s\n", i, codec->name);
- printf("Stream %d codec long name: %s\n", i, codec->long_name);
- putc('\n', stdout);
- if (codecParams->codec_type == AVMEDIA_TYPE_VIDEO) {
- videoStreamInd = i;
- videoCodec = codec;
- videoCodecParams = codecParams;
- }
- }
- AVCodecContext* videoCtx = avcodec_alloc_context3(videoCodec);
- if (videoCtx == NULL) {
- puts("couldn't allocate a codec context");
- return -1;
- }
- res = avcodec_parameters_to_context(videoCtx, videoCodecParams);
- if (res < 0) {
- puts("couldn't send codec parameters to the codec context");
- return -1;
- }
- res = avcodec_open2(videoCtx, videoCodec, NULL);
- if (res < 0) {
- puts("couldn't open the codec context");
- return -1;
- }
- AVPacket* packet = av_packet_alloc();
- if (packet == NULL) {
- puts("couldn't allocate a packet");
- return -1;
- }
- AVFrame* frame = av_frame_alloc();
- if (frame == NULL) {
- puts("couldn't allocate a frame");
- return -1;
- }
- AVFrame* rgbaFrame = av_frame_alloc();
- if (frame == NULL) {
- puts("couldn't allocate an RGBA frame");
- return -1;
- }
- int size = avpicture_get_size(AV_PIX_FMT_RGBA, videoCtx->width, videoCtx->height);
- uint8_t* buf = (uint8_t*)av_malloc(size * sizeof(uint8_t));
- avpicture_fill((AVPicture*)rgbaFrame, buf, AV_PIX_FMT_RGBA, videoCtx->width, videoCtx->height);
- SwsContext* swsCtx = sws_getContext(videoCtx->width, videoCtx->height, videoCtx->pix_fmt,
- videoCtx->width, videoCtx->height, AV_PIX_FMT_RGBA, SWS_BICUBIC, NULL, NULL, NULL);
- int i = 0;
- while (av_read_frame(ctx, packet) >= 0)
- {
- if (packet->stream_index != videoStreamInd) {
- continue;
- }
- res = avcodec_send_packet(videoCtx, packet);
- if (res < 0) {
- printf("couldn't send the packet to the decoder %d\n", res);
- continue;
- }
- res = avcodec_receive_frame(videoCtx, frame);
- if (res < 0) {
- puts("couldn't receive the frame from the decoder\n");
- continue;
- }
- printf(
- "Frame %c (%d) pts %d dts %d key_frame %d [coded_picture_number %d, display_picture_number %d]\n",
- av_get_picture_type_char(frame->pict_type),
- videoCtx->frame_number,
- frame->pts,
- frame->pkt_dts,
- frame->key_frame,
- frame->coded_picture_number,
- frame->display_picture_number
- );
- // Transcode to RGBA.
- sws_scale(swsCtx, frame->data, frame->linesize, 0, videoCtx->height, rgbaFrame->data, rgbaFrame->linesize);
- char buffer[32];
- sprintf(buffer, "frame_%d.pgm", i);
- save_gray_frame(frame->data[0], frame->linesize[0], frame->width, frame->height, buffer);
- i++;
- if (i == 7) {
- break;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement