国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ffmpeg實(shí)現(xiàn)視頻解碼

這篇具有很好參考價(jià)值的文章主要介紹了ffmpeg實(shí)現(xiàn)視頻解碼。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

參考100行代碼實(shí)現(xiàn)最簡(jiǎn)單的基于FFMPEG+SDL的視頻播放器(SDL1.x)

雷神的代碼用在VS2022編譯需要做些調(diào)整

平臺(tái)環(huán)境:windows VS 2022

#pragma comment(lib, "legacy_stdio_definitions.lib") //此為添加的代碼
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavutil/imgutils.h"
#include "SDL2/SDL.h"
	FILE __iob_func[3] = { *stdin,*stdout,*stderr };
};

以及在
項(xiàng)目->項(xiàng)目屬性->鏈接器->命令行,在右側(cè)其他選項(xiàng)中添加“/SAFESEH:NO”,這樣就不會(huì)再報(bào)錯(cuò)了。

使用ffmpeg進(jìn)行解碼的一般步驟

1.初始化FFmpeg庫(kù):

在代碼中引入相關(guān)的FFmpeg頭文件,并調(diào)用初始化函數(shù)。例如:

av_register_all();
avcodec_register_all();
avformat_network_init();

2.打開(kāi)輸入文件:

使用avformat_open_input,avformat_open_input 函數(shù)是FFmpeg(一個(gè)開(kāi)源的多媒體處理庫(kù))中的一個(gè)函數(shù),用于打開(kāi)音視頻文件或者網(wǎng)絡(luò)流,并將其封裝格式的相關(guān)信息填充到一個(gè) AVFormatContext 結(jié)構(gòu)體中。這個(gè)函數(shù)通常是在處理音視頻文件時(shí)的初始步驟之一。

AVFormatContext *pFormatCtx;
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);

參數(shù)解釋:
ps: 用于存儲(chǔ) AVFormatContext 結(jié)構(gòu)體指針的指針。AVFormatContext 是一個(gè)保存音視頻文件或流相關(guān)信息的結(jié)構(gòu)體,就是句柄。

url: 要打開(kāi)的音視頻文件或者網(wǎng)絡(luò)流的URL。

fmt: 指定輸入格式。通??梢栽O(shè)置為 NULL,表示由FFmpeg自動(dòng)檢測(cè)輸入格式。

options: 一個(gè)指向 AVDictionary 結(jié)構(gòu)體指針的指針,用于傳遞附加的選項(xiàng)。可以為 NULL,表示沒(méi)有額外選項(xiàng)。

3.獲取流信息

使用 avformat_find_stream_info函數(shù),avformat_find_stream_info 函數(shù)是FFmpeg庫(kù)中用于獲取音視頻流詳細(xì)信息的函數(shù)。在打開(kāi)音視頻文件或者網(wǎng)絡(luò)流后,通常需要調(diào)用這個(gè)函數(shù)來(lái)獲取音視頻流的相關(guān)信息,如編碼格式、分辨率、幀率等。

int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

參數(shù)解釋:
ic: AVFormatContext 結(jié)構(gòu)體,它包含了音視頻文件或者網(wǎng)絡(luò)流的相關(guān)信息,通常是通過(guò) avformat_open_input 打開(kāi)的。

options: 一個(gè)指向 AVDictionary 結(jié)構(gòu)體指針的指針,用于傳遞附加的選項(xiàng)??梢詾?NULL,表示沒(méi)有額外選項(xiàng)。

函數(shù)返回值是一個(gè)整數(shù),表示函數(shù)執(zhí)行的結(jié)果。通常,如果函數(shù)成功執(zhí)行,則返回 0,否則返回一個(gè)負(fù)數(shù)表示錯(cuò)誤。

4.找到視頻流索引并獲取解碼器上下文:

通過(guò)遍歷流信息,找到視頻流的索引,然后獲取視頻解碼器的上下文。

int videoStreamIndex = -1;
for (int i = 0; i < pFormatCtx->nb_streams; i++) {
    if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
        videoStreamIndex = i;
        break;
    }
}
AVCodecContext *pCodecCtx = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStreamIndex]->codecpar);

5.查找并打開(kāi)解碼器:

使用avcodec_find_decoder函數(shù)查找合適的解碼器,并使用avcodec_open2打開(kāi)解碼器。

AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
avcodec_open2(pCodecCtx, pCodec, NULL);

6.創(chuàng)建幀和包:

創(chuàng)建用于存儲(chǔ)解碼后的幀的AVFrame對(duì)象以及用于存儲(chǔ)解碼前的數(shù)據(jù)包的AVPacket對(duì)象。

AVFrame *pFrame = av_frame_alloc();
AVPacket *pPacket = av_packet_alloc();

7.解碼:

使用循環(huán)讀取每個(gè)數(shù)據(jù)包,將數(shù)據(jù)包發(fā)送到解碼器進(jìn)行解碼,得到解碼后的幀。

while (av_read_frame(pFormatCtx, pPacket) >= 0) {
    if (pPacket->stream_index == videoStreamIndex) {
        avcodec_receive_frame(pCodecCtx, pFrame);
        // 處理解碼后的幀(顯示、保存等)
    }
    av_packet_unref(pPacket);
}

8.釋放資源

avformat_close_input(&pFormatCtx);
avcodec_free_context(&pCodecCtx);
av_frame_free(&pFrame);
av_packet_free(&pPacket);

使用ffmpeg解碼視頻文件

本例子使用FFmpeg庫(kù)解碼視頻文件,并將解碼后的幀保存為PPM圖像文件。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-819660.html

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>

#define IN_FILE_PATH "input_video.mp4"
#define OUT_FILE_PATH "output_frame.ppm"

int main() {
    AVFormatContext *pFormatCtx = NULL;
    AVCodecContext *pCodecCtx = NULL;
    AVCodec *pCodec = NULL;
    AVFrame *pFrame = NULL;
    AVPacket packet;
    struct SwsContext *pSwsCtx = NULL;

    // Register all formats and codecs
    av_register_all();

    // Open input file
    if (avformat_open_input(&pFormatCtx, IN_FILE_PATH, NULL, NULL) != 0) {
        fprintf(stderr, "Could not open input file\n");
        return -1;
    }

    // Retrieve stream information
    if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
        fprintf(stderr, "Could not find stream information\n");
        return -1;
    }

    // Find the first video stream
    int videoStream = -1;
    for (int i = 0; i < pFormatCtx->nb_streams; i++) {
        if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStream = i;
            break;
        }
    }

    if (videoStream == -1) {
        fprintf(stderr, "Could not find a video stream\n");
        return -1;
    }

    // Get a pointer to the codec context for the video stream
    pCodec = avcodec_find_decoder(pFormatCtx->streams[videoStream]->codecpar->codec_id);
    if (pCodec == NULL) {
        fprintf(stderr, "Unsupported codec\n");
        return -1;
    }

    pCodecCtx = avcodec_alloc_context3(pCodec);
    if (avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar) < 0) {
        fprintf(stderr, "Failed to copy codec parameters to codec context\n");
        return -1;
    }

    // Open codec
    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
        fprintf(stderr, "Could not open codec\n");
        return -1;
    }

    // Allocate video frame
    pFrame = av_frame_alloc();

    // Setup scaler context to convert video frames to RGB
    pSwsCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
                             pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24,
                             SWS_BILINEAR, NULL, NULL, NULL);

    if (pSwsCtx == NULL) {
        fprintf(stderr, "Failed to allocate SwsContext\n");
        return -1;
    }

    // Open output file for writing PPM
    FILE *ppmFile = fopen(OUT_FILE_PATH, "wb");
    if (ppmFile == NULL) {
        fprintf(stderr, "Could not open output file\n");
        return -1;
    }

    // Read frames and save as PPM
    while (av_read_frame(pFormatCtx, &packet) >= 0) {
        if (packet.stream_index == videoStream) {
            // Decode video frame
            int response = avcodec_send_packet(pCodecCtx, &packet);
            if (response < 0) {
                fprintf(stderr, "Error decoding frame (avcodec_send_packet)\n");
                break;
            }

            while (response >= 0) {
                response = avcodec_receive_frame(pCodecCtx, pFrame);
                if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
                    break;
                } else if (response < 0) {
                    fprintf(stderr, "Error decoding frame (avcodec_receive_frame)\n");
                    break;
                }

                // Convert the frame to RGB
                uint8_t *buffer = NULL;
                int numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 1);
                buffer = av_malloc(numBytes * sizeof(uint8_t));

                av_image_fill_arrays(pFrame->data, pFrame->linesize, buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 1);

                sws_scale(pSwsCtx, (uint8_t const * const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);

                // Save the frame as PPM
                fprintf(ppmFile, "P6\n%d %d\n255\n", pCodecCtx->width, pCodecCtx->height);
                fwrite(buffer, 1, numBytes, ppmFile);

                av_free(buffer);
            }
        }

        av_packet_unref(&packet);
    }

    // Clean up
    av_frame_free(&pFrame);
    avcodec_close(pCodecCtx);
    avformat_close_input(&pFormatCtx);
    sws_freeContext(pSwsCtx);
    fclose(ppmFile);

    return 0;
}

到了這里,關(guān)于ffmpeg實(shí)現(xiàn)視頻解碼的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【配置環(huán)境】安裝Ffmpeg音視頻編解碼工具和搭建EasyDarwin開(kāi)源流媒體服務(wù)器

    【配置環(huán)境】安裝Ffmpeg音視頻編解碼工具和搭建EasyDarwin開(kāi)源流媒體服務(wù)器

    目錄 一,安裝Ffmpeg音視頻編解碼工具 1,簡(jiǎn)介 2,開(kāi)發(fā)文檔 3,安裝部署 二,搭建EasyDarwin開(kāi)源流媒體服務(wù)器 1,簡(jiǎn)介 2,主要功能特點(diǎn) 3,安裝部署 4,效果圖 三,簡(jiǎn)單測(cè)試 Ffmpeg是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開(kāi)源計(jì)算機(jī)程序。采用LGPL或GPL許

    2024年02月07日
    瀏覽(122)
  • FFmpeg源碼分析:avcodec_send_packet()與avcodec_receive_frame()音視頻解碼

    FFmpeg源碼分析:avcodec_send_packet()與avcodec_receive_frame()音視頻解碼

    FFmpeg在libavcodec模塊,舊版本提供avcodec_decode_video2()作為視頻解碼函數(shù),avcodec_decode_audio4()作為音頻解碼函數(shù)。在FFmpeg 3.1版本新增avcodec_send_packet()與avcodec_receive_frame()作為音視頻解碼函數(shù)。后來(lái),在3.4版本把a(bǔ)vcodec_decode_video2()和avcodec_decode_audio4()標(biāo)記為過(guò)時(shí)API。版本變更描述如下

    2024年02月03日
    瀏覽(94)
  • FFmpeg 音視頻開(kāi)發(fā)工具

    FFmpeg 音視頻開(kāi)發(fā)工具

    目錄 FFmpeg 下載與安裝 ffmpeg 使用快速入門 ffplay 使用快速入門 1、FFmpeg 是處理音頻、視頻、字幕和相關(guān)元數(shù)據(jù)等多媒體內(nèi)容的庫(kù)和工具的集合。一個(gè)完整的跨平臺(tái)解決方案,用于錄制、轉(zhuǎn)換和流式傳輸音頻和視頻。 官網(wǎng):https://www.ffmpeg.org/ 源碼:https://github.com/FFmpeg/FFmpeg。

    2024年02月15日
    瀏覽(29)
  • 音視頻開(kāi)發(fā)---ffmpeg rtmp推流

    音視頻開(kāi)發(fā)---ffmpeg rtmp推流

    推流是將輸入視頻數(shù)據(jù)推送至流媒體服務(wù)器, 輸入視頻數(shù)據(jù)可以是本地視頻文件(avi,mp4,flv......),也可以是內(nèi)存視頻數(shù)據(jù),或者攝像頭等系統(tǒng)設(shè)備,也可以是網(wǎng)絡(luò)流URL。本篇介紹將本地視頻文件通過(guò)FFmpeg編程以RTMP直播流的形式推送至RTMP流媒體服務(wù)器的方法。 推流的網(wǎng)絡(luò)拓?fù)?/p>

    2024年02月16日
    瀏覽(34)
  • 音視頻開(kāi)發(fā)-ffmpeg介紹-系列一

    音視頻開(kāi)發(fā)-ffmpeg介紹-系列一

    目錄 一.簡(jiǎn)介 FFmpeg框架的基本組成包含: 二.?FFmpeg框架梳理音視頻的流程?編輯 基本概念: 三.ffmpeg、ffplay、ffprobe區(qū)別 ? ? ?4.1 ffmpeg是用于轉(zhuǎn)碼的應(yīng)用程序? 4.2?fffplay是用于播放的應(yīng)用程序? ? ? ?4.3?ffprobe是用于查看文件格式的應(yīng)用程序 ? ? ?4.4?ffmpeg是用于轉(zhuǎn)碼的應(yīng)用程

    2024年02月16日
    瀏覽(30)
  • 玩賺音視頻開(kāi)發(fā)高階技術(shù)——FFmpeg

    玩賺音視頻開(kāi)發(fā)高階技術(shù)——FFmpeg

    隨著移動(dòng)互聯(lián)網(wǎng)的普及,人們對(duì)音視頻內(nèi)容的需求也不斷增加。無(wú)論是社交媒體平臺(tái)、電商平臺(tái)還是在線教育,都離不開(kāi)音視頻的應(yīng)用。這就為音視頻開(kāi)發(fā)人員提供了廣闊的就業(yè)機(jī)會(huì)。根據(jù)這些年來(lái)網(wǎng)站上的音視頻開(kāi)發(fā)招聘需求來(lái)看,音視頻開(kāi)發(fā)人員的需求量大,且薪資待遇

    2024年02月13日
    瀏覽(29)
  • Qt音視頻開(kāi)發(fā)38-ffmpeg視頻暫停錄制的設(shè)計(jì)

    Qt音視頻開(kāi)發(fā)38-ffmpeg視頻暫停錄制的設(shè)計(jì)

    基本上各種播放器提供的錄制視頻接口,都是只有開(kāi)始錄制和結(jié)束錄制兩個(gè),當(dāng)然一般用的最多的也是這兩個(gè)接口,但是實(shí)際使用過(guò)程中,還有一種可能需要中途暫停錄制,暫停以后再次繼續(xù)錄制,將中間部分視頻不需要錄制,跳過(guò)這部分不需要的視頻,而且錄制的視頻文件

    2023年04月20日
    瀏覽(25)
  • Android 音視頻開(kāi)發(fā)實(shí)踐系列-06-初步了解H.264視頻編解碼技術(shù)標(biāo)準(zhǔn)

    Android 音視頻開(kāi)發(fā)實(shí)踐系列-06-初步了解H.264視頻編解碼技術(shù)標(biāo)準(zhǔn)

    本文來(lái)自筆者本人的語(yǔ)雀博客,由于語(yǔ)雀升級(jí)后不再滿足筆者的需求,因此之后筆者會(huì)陸續(xù)將一些之前已經(jīng)發(fā)布但尚有價(jià)值的文章搬家到CSDN。 作為音視頻行業(yè)從業(yè)者,怎么能不理解H.264視頻編解碼技術(shù)標(biāo)準(zhǔn)?本篇文章主要記錄筆者學(xué)習(xí)過(guò)程中對(duì)眾多優(yōu)秀博客內(nèi)容的摘抄整理,

    2023年04月09日
    瀏覽(33)
  • 音視頻處理 ffmpeg中級(jí)開(kāi)發(fā) H264編碼

    音視頻處理 ffmpeg中級(jí)開(kāi)發(fā) H264編碼

    libavcodec/avcodec.h 常用的數(shù)據(jù)結(jié)構(gòu) AVCodec 編碼器結(jié)構(gòu)體 AVCodecContext 編碼器上下文 AVFrame 解碼后的幀 結(jié)構(gòu)體內(nèi)存的分配和釋放 av_frame_alloc 申請(qǐng) av_frame_free() 釋放 avcodec_alloc_context3() 創(chuàng)建編碼器上下文 avcodec_free_context() 釋放編碼器上下文 解碼步驟 avcodec_find_decoder 查找解碼器 avcod

    2024年02月01日
    瀏覽(109)
  • 音視頻開(kāi)發(fā)實(shí)戰(zhàn)03-FFmpeg命令行工具移植

    音視頻開(kāi)發(fā)實(shí)戰(zhàn)03-FFmpeg命令行工具移植

    作為一個(gè)音視頻開(kāi)發(fā)者,在日常工作中經(jīng)常會(huì)使用ffmpeg 命令來(lái)做很多事比如轉(zhuǎn)碼 ffmpeg -y -i test.mov -g 150 -s 1280x720 -codec libx265 -r 25 test_h265.mp4 ,水平翻轉(zhuǎn)視頻: ffmpeg -i src.mp4 -vf hflip -acodec copy -vcodec h264 -b 22000000 out.mp4 ,視頻截?。?ffmpeg -i input.wmv -ss 00:00:30.0 -c copy -t 00:00:10.0 ou

    2024年02月16日
    瀏覽(31)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包