FFmpeg實現(xiàn)解封裝

一闷煤、關(guān)鍵函數(shù)介紹:

1童芹、av_register_all()

注冊所有的解封裝格式,也可以根據(jù)不同的封裝格式曹傀,單個注冊辐脖。

2、avcodec_register_all()

網(wǎng)絡注冊皆愉,如rtsp和http的

3、打開文件
//AVFormatContext 封裝的結(jié)構(gòu)體,創(chuàng)建一個內(nèi)容為空的指針艇抠,內(nèi)部可以自己管理ic
AVFormatContext *ic = NULL;  
int re = avformat_open_input(&ic, path, 0, 0);

根據(jù)re的結(jié)果可以判斷是否成功

4幕庐、獲取流信息
 avformat_find_stream_info(ic, 0)
5、獲取音頻流信息
//返回的是音頻索引
av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0)
6家淤、拖動timestamp時間的frame
/**
 * Seek to the keyframe at timestamp.
 * 'timestamp' in 'stream_index'.
 *
 * @param s media file handle
 * @param stream_index If stream_index is (-1), a default
 * stream is selected, and timestamp is automatically converted
 * from AV_TIME_BASE units to the stream specific time_base.
 * @param timestamp Timestamp in AVStream.time_base units
 *        or, if no stream is specified, in AV_TIME_BASE units.
 * @param flags flags which select direction and seeking mode
 * @return >= 0 on success
 */
    av_seek_frame(ic, videoStream, pos, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME);
7异剥、讀取下一幀
// 返回值<0代表錯誤或者讀完了
int av_read_frame(AVFormatContext *s, AVPacket *pkt);

二、關(guān)鍵結(jié)構(gòu)體介紹:

1搓幌、AVFormatContext
AVIOContext *pb; // I/O context.自定義格式讀或者從內(nèi)存讀可用
char filename[1024]; // input or output filename

 /**
  * Number of elements in AVFormatContext.streams.
 */
unsigned int nb_streams; // 流的數(shù)量
/**
 * A list of all streams in the file. New streams are created with
 * avformat_new_stream().
 *
 * - demuxing: streams are created by libavformat in avformat_open_input().
 *             If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also
 *             appear in av_read_frame().
 * - muxing: streams are created by the user before avformat_write_header().
 *
 * Freed by libavformat in avformat_free_context().
 */
AVStream **streams; //音視頻字幕流

/**
 * Duration of the stream, in AV_TIME_BASE fractional
 * seconds. Only set this value if you know none of the individual stream
 * durations and also do not set any of them. This is deduced from the
 * AVStream values if not set.
 *
 * Demuxing only, set by libavformat.
 */
int64_t duration; // 獲取的總長度(不一定能獲取的到晌梨,也可通過AVStream獲取)
   /**
 * Total stream bitrate in bit/s, 0 if not
 * available. Never set it directly if the file_size and the
 * duration are known as FFmpeg can compute it automatically.
 */
int64_t bit_rate; // 比特率梦谜,網(wǎng)絡適應的時候會用
/**
* Close an opened input AVFormatContext. Free it and all its contents
* and set *s to NULL.
*/
void avformat_close_input(AVFormatContext **s);// 關(guān)閉
2督怜、AVStream
    /**
     * This is the fundamental unit of time (in seconds) in terms
     * of which frame timestamps are represented.
     */
    AVRational time_base; //時間基數(shù)殴瘦,通過分子分母計算  (double) r.num / (double) r.den
    /**
     * Decoding: duration of the stream, in stream time base.
     * If a source file does not specify a duration, but does specify
     * a bitrate, this value will be estimated from bitrate and file size.
     *
     * Encoding: May be set by the caller before avformat_write_header() to
     * provide a hint to the muxer about the estimated duration.
     */
    int64_t duration; //換算成秒

    int64_t nb_frames;                 ///< number of frames in this stream if known or 0
3、AVCodecParameters

Codec parameters associated with this stream.

    /**
     * General type of the encoded data.
     */
    enum AVMediaType codec_type; // 標志是否是音頻還是視頻
    /**
     * Specific type of the encoded data (the codec used).
     */
    enum AVCodecID   codec_id; // 對應的編碼格式 h264還是其它的

    /**
     * - video: the pixel format, the value corresponds to enum AVPixelFormat.
     * - audio: the sample format, the value corresponds to enum AVSampleFormat.
     */
    int format; // 音視頻不一樣
    /**
     * Video only. The dimensions of the video frame in pixels.
     */
    int width;
    int height;
    /**
     * Audio only. The number of audio channels.
     */
    int      channels;
    /**
     * Audio only. The number of audio samples per second.
     */
    int      sample_rate;
4号杠、AVPacket
    /**
     * Presentation timestamp in AVStream->time_base units; the time at which
     * the decompressed packet will be presented to the user.
     * Can be AV_NOPTS_VALUE if it is not stored in the file.
     * pts MUST be larger or equal to dts as presentation cannot happen before
     * decompression, unless one wants to view hex dumps. Some formats misuse
     * the terms dts and pts/cts to mean something different. Such timestamps
     * must be converted to true pts/dts before they are stored in AVPacket.
     */
    int64_t pts; // 顯示時間
    /**
     * Decompression timestamp in AVStream->time_base units; the time at which
     * the packet is decompressed.
     * Can be AV_NOPTS_VALUE if it is not stored in the file.
     */
    int64_t dts; // 解碼時間
    uint8_t *data;
    int   size;

幾個重要函數(shù):

  AVPacket *pkt = av_packet_alloc(); //創(chuàng)建對象并初始化
  AVPacket *av_packet_clone(const AVPacket *src);創(chuàng)建并并用計數(shù)
  int av_packet_ref(AVPacket *dst, const AVPacket *src);
  av_packet_unref(AVPacket *pkt)
  void av_packet_free(AVPacket **pkt); 清空對象并減引用計數(shù)
  void av_init_packet(AVPacket *pkt); 默認值
  int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size);
  int av_copy_packet(AVPacket *dst, const AVPacket *src); attribute_deprecated

3蚪腋、解封裝部分代碼

   //初始化解封裝
    av_register_all();
    //初始化網(wǎng)絡
    avformat_network_init();

    avcodec_register_all();

    //打開文件
    AVFormatContext *ic = NULL;
    //char path[] = "/sdcard/video.flv";
    int re = avformat_open_input(&ic, path, 0, 0);
    if (re != 0) {
        LOGW("avformat_open_input failed!:%s", av_err2str(re));
        return;
    }
    LOGW("avformat_open_input %s success!", path);
    //獲取流信息
    re = avformat_find_stream_info(ic, 0);
    if (re != 0) {
        LOGW("avformat_find_stream_info failed!");
    }
    LOGE("duration = %lld nb_streams = %d", ic->duration, ic->nb_streams);

    int fps = 0;
    int videoStream = 0;
    int audioStream = 1;



    /**
     *  音視頻屬性打印
     */
    for (int i = 0; i < ic->nb_streams; i++) {
        AVStream *as = ic->streams[i];
        // 視頻流
        if (as->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            LOGW("視頻數(shù)據(jù)");
            videoStream = i;
            fps = r2d(as->avg_frame_rate);

            LOGW("fps = %d,width=%d height=%d codeid=%d pixformat=%d", fps,
                 as->codecpar->width,
                 as->codecpar->height,
                 as->codecpar->codec_id,
                 as->codecpar->format
            );
            //音頻流
        } else if (as->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
            LOGW("音頻數(shù)據(jù)");
            audioStream = i;
            LOGW("sample_rate=%d channels=%d sample_format=%d",
                 as->codecpar->sample_rate,
                 as->codecpar->channels,
                 as->codecpar->format
            );
        }
    }

    // 除了上述中的遍歷方法,還可以通過下列av_find_best_stream函數(shù)尋找音視頻索引
    //獲取音頻流信息
    audioStream = av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
    videoStream = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);;
    LOGW("av_find_best_stream audioStream = %d  videoStream = %d", audioStream,videoStream);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姨蟋,一起剝皮案震驚了整個濱河市屉凯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眼溶,老刑警劉巖悠砚,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異堂飞,居然都是意外死亡哩簿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門酝静,熙熙樓的掌柜王于貴愁眉苦臉地迎上來节榜,“玉大人,你說我怎么就攤上這事别智∽诓裕” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵薄榛,是天一觀的道長讳窟。 經(jīng)常有香客問我,道長敞恋,這世上最難降的妖魔是什么丽啡? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮硬猫,結(jié)果婚禮上补箍,老公的妹妹穿的比我還像新娘。我一直安慰自己啸蜜,他們只是感情好坑雅,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著衬横,像睡著了一般裹粤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜂林,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天遥诉,我揣著相機與錄音拇泣,去河邊找鬼。 笑死矮锈,一個胖子當著我的面吹牛霉翔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播愕难,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼早龟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了猫缭?” 一聲冷哼從身側(cè)響起葱弟,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎猜丹,沒想到半個月后芝加,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡射窒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年藏杖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脉顿。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡蝌麸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出艾疟,到底是詐尸還是另有隱情来吩,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布蔽莱,位于F島的核電站弟疆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏盗冷。R本人自食惡果不足惜怠苔,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仪糖。 院中可真熱鬧柑司,春花似錦、人聲如沸乓诽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸠天。三九已至,卻和暖如春帐姻,著一層夾襖步出監(jiān)牢的瞬間稠集,已是汗流浹背奶段。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剥纷,地道東北人痹籍。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像晦鞋,于是被迫代替她去往敵國和親蹲缠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 教程一:視頻截圖(Tutorial 01: Making Screencaps) 首先我們需要了解視頻文件的一些基...
    90后的思維閱讀 4,697評論 0 3
  • FFmpeg 介紹 FFmpeg是一套可以用來記錄悠垛、轉(zhuǎn)換數(shù)字音頻线定、視頻,并能將其轉(zhuǎn)化為流的開源計算機程序确买。采用LG...
    Y了個J閱讀 11,284評論 0 28
  • 寫在前面 如果對FFmpeg有需要更多了解的請訂閱我的專題:音視頻專輯 3.1 FFmpeg 文件結(jié)構(gòu) libav...
    張芳濤閱讀 2,563評論 0 21
  • ffmpeg是一個非常有用的命令行程序斤讥,它可以用來轉(zhuǎn)碼媒體文件。它是領先的多媒體框架FFmpeg的一部分湾趾,其有很多...
    城市之光閱讀 6,777評論 3 6
  • 對于FFMPEG是只聞其名芭商,不見其人,各個大廠比如QQ影音搀缠,Bilibili等等都是以它為基礎的铛楣。(好多都是從雷神...
    豬_隊友閱讀 430評論 0 1