FFmpeg之decode_video

#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
#ifdef __cplusplus
};
#endif

int main()
{
    //文件格式上下文
    AVFormatContext	*pFormatCtx;
    int		i = 0, videoindex;
    AVCodecContext	*pCodecCtx;
    AVCodec			*pCodec;
    AVFrame	*pFrame, *pFrameYUV;
    unsigned char *out_buffer;
    AVPacket *packet;

    int y_size;
    int ret, got_picture;
    struct SwsContext *img_convert_ctx;
    char filepath[] = "/home/mmm/视频/阳光电影www.ygdy8.com.寄生虫.BD.1080p.韩语中字.mkv";
    FILE *fp_yuv = fopen("output.yuv", "wb+");
    av_register_all();
    avformat_network_init();
    pFormatCtx = avformat_alloc_context();
    if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0)
    {
        printf("Couldn't open input stream.\n");
        return -1;
    }
    //读取一部分视音频数据并且获得一些相关的信息
    if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
    {
        printf("Couldn't find stream information.\n");
        return -1;
    }

    //查找视频编码索引
    videoindex = -1;
    for (i = 0; i < pFormatCtx->nb_streams; i++)
    {
        if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            videoindex = i;
            break;
        }
    }

    if (videoindex == -1)
    {
        printf("Didn't find a video stream.\n");
        return -1;
    }

    //编解码上下文
    pCodecCtx = pFormatCtx->streams[videoindex]->codec;
    //查找解码器
    pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
    if (pCodec == nullptr)
    {
        printf("Codec not found.\n");
        return -1;
    }
    //打开解码器
    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
    {
        printf("Could not open codec.\n");
        return -1;
    }

    //申请AVFrame,用于原始视频
    pFrame = av_frame_alloc();
    //申请AVFrame,用于yuv视频
    pFrameYUV = av_frame_alloc();
    //分配内存,用于图像格式转换
    out_buffer = (unsigned char *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1));
    av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, out_buffer,AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
    packet = (AVPacket *)av_malloc(sizeof(AVPacket));
    //Output Info-----------------------------
    printf("--------------- File Information ----------------\n");
    //手工调试函数,输出tbn、tbc、tbr、PAR、DAR的含义
    av_dump_format(pFormatCtx, 0, filepath, 0);
    printf("-------------------------------------------------\n");

    //申请转换上下文
    img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
    pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);

    //读取数据
    while (av_read_frame(pFormatCtx, packet) >= 0)
    {
        if (packet->stream_index == videoindex)
        {
            ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
            if (ret < 0)
            {
                printf("Decode Error.\n");
                return -1;
            }

            if (got_picture >= 1)
            {
                //成功解码一帧
                sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
                    pFrameYUV->data, pFrameYUV->linesize);//转换图像格式

                y_size = pCodecCtx->width*pCodecCtx->height;
                fwrite(pFrameYUV->data[0], 1, y_size, fp_yuv);    //Y
                fwrite(pFrameYUV->data[1], 1, y_size / 4, fp_yuv);  //U
                fwrite(pFrameYUV->data[2], 1, y_size / 4, fp_yuv);  //V
                printf("Succeed to decode 1 frame!\n");
            }
            else
            {
                //未解码到一帧,可能时结尾B帧或延迟帧,在后面做flush decoder处理
            }
        }
        av_free_packet(packet);
    }

    //flush decoder
    //FIX: Flush Frames remained in Codec
    while (true)
    {
        if (!(pCodec->capabilities & CODEC_CAP_DELAY))
            return 0;

        ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
        if (ret < 0)
        {
            break;
        }
        if (!got_picture)
        {
            break;
        }

        sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
            pFrameYUV->data, pFrameYUV->linesize);

        int y_size = pCodecCtx->width*pCodecCtx->height;
        fwrite(pFrameYUV->data[0], 1, y_size, fp_yuv);    //Y
        fwrite(pFrameYUV->data[1], 1, y_size / 4, fp_yuv);  //U
        fwrite(pFrameYUV->data[2], 1, y_size / 4, fp_yuv);  //V
        printf("Flush Decoder: Succeed to decode 1 frame!\n");
    }

    sws_freeContext(img_convert_ctx);
    av_frame_free(&pFrameYUV);
    av_frame_free(&pFrame);
    avcodec_close(pCodecCtx);
    avformat_close_input(&pFormatCtx);
    fclose(fp_yuv);

    return 0;
}

 

build-qt_ffmpeg-Desktop_Qt_5_12_6_GCC_64bit-Debug/qt_ffmpeg 被光抓走的人.mp4...

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '被光抓走的人.mp4':

Metadata:

major_brand : isom

minor_version : 512

compatible_brands: isomiso2avc1mp41

encoder : Lavf58.29.100

Duration: 02:11:00.07, start: 0.000000, bitrate: 1603 kb/s Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1040, 1472 kb/s, 24 fps, 24 tbr, 90k tbn, 48 tbc (default)

Metadata:

handler_name : VideoHandler

Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 124 kb/s (default)

Metadata:

handler_name : SoundHandler

--------------- File Information ----------------

-------------------------------------------------

Succeed to decode 1 frame!

Succeed to decode 1 frame!

Succeed to decode 1 frame!

Succeed to decode 1 frame!

Succeed to decode 1 frame!

Succeed to decode 1 frame!

Succeed to decode 1 frame!

Succeed to decode 1 frame!

 

 

Desktop_Qt_5_12_6_GCC_64bit-Debug/qt_ffmpeg 被光抓走的人.mp4...

Input #0, matroska,webm, from '/home/mmm/视频/Mile.22.2018.1080p.WEB-DL.DD5.1.H264-FGT.mkv':

Metadata:

title : Mile.22.2018.1080p.WEB-DL.DD5.1.H264-FGT

encoder : libebml v1.3.6 + libmatroska v1.4.9

creation_time : 2018-10-30T05:12:55.000000Z

Duration: 01:34:39.89, start: 0.000000, bitrate: 4921 kb/s

Chapter #0:0: start 0.000000, end 976.643000

Metadata:

title : Chapter 01

Chapter #0:1: start 976.643000, end 1516.057000 Metadata:

title : Chapter 02

Chapter #0:2: start 1516.057000, end 2193.692000

Metadata:

title : Chapter 03

Chapter #0:3: start 2193.692000, end 2787.869000

Metadata:

title : Chapter 04

Chapter #0:4: start 2787.869000, end 3554.135000

Metadata:

title : Chapter 05

Chapter #0:5: start 3554.135000, end 4059.890000

Metadata:

title : Chapter 06

Chapter #0:6: start 4059.890000, end 4702.908000

Metadata:

title : Chapter 07

Chapter #0:7: start 4702.908000, end 5234.814000

Metadata:

title : Chapter 08

Chapter #0:8: start 5234.814000, end 5679.889000

Metadata:

title : Chapter 09

Stream #0:0(eng): Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x800 [SAR 1:1 DAR 12:5], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)

Metadata:

title : Mile.22.2018.1080p.WEB-DL.DD5.1.H264-FGT

BPS-eng : 4535970

DURATION-eng : 01:34:39.847000000

NUMBER_OF_FRAMES-eng: 136180

NUMBER_OF_BYTES-eng: 3220452265

_STATISTICS_WRITING_APP-eng: mkvmerge v28.1.0 ('Morning Child') 64-bit

_STATISTICS_WRITING_DATE_UTC-eng: 2018-10-30 05:12:55

_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES

Stream #0:1(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s (default)

Metadata:

title : Mile.22.2018.1080p.WEB-DL.DD5.1.H264-FGT

BPS-eng : 384000

DURATION-eng : 01:34:39.872000000

NUMBER_OF_FRAMES-eng: 177496

NUMBER_OF_BYTES-eng: 272633856

_STATISTICS_WRITING_APP-eng: mkvmerge v28.1.0 ('Morning Child') 64-bit

_STATISTICS_WRITING_DATE_UTC-eng: 2018-10-30 05:12:55

_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES

Stream #0:2: Video: mjpeg, yuvj444p(pc, bt470bg/unknown/unknown), 120x176, 90k tbr, 90k tbn, 90k tbc

Metadata:

filename : small_cover.jpg

mimetype : image/jpeg

Stream #0:3: Video: mjpeg, yuvj444p(pc, bt470bg/unknown/unknown), 213x120, 90k tbr, 90k tbn, 90k tbc

Metadata:

filename : small_cover_land.jpg

mimetype : image/jpeg

Stream #0:4: Video: mjpeg, yuvj444p(pc, bt470bg/unknown/unknown), 600x882, 90k tbr, 90k tbn, 90k tbc

Metadata:

filename : cover.jpg

mimetype : image/jpeg

Stream #0:5: Video: mjpeg, yuvj444p(pc, bt470bg/unknown/unknown), 1067x600, 90k tbr, 90k tbn, 90k tbc

Metadata:

filename : cover_land.jpg

mimetype : image/jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值