<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ?FFMPEG函數(shù)分析av_read_frame()

          共 2008字,需瀏覽 5分鐘

           ·

          2022-01-12 01:14

          點(diǎn)擊關(guān)注,與你共同成長!




          FFMPEG函數(shù)分析av_read_frame()

          簡介

          對于視頻的編解碼來說,要對數(shù)據(jù)進(jìn)行解碼,那么首先要獲取視頻幀的壓縮數(shù)據(jù)。

          av_read_frame()的作用就是獲取視頻的數(shù)據(jù)

          注:av_read_frame()獲取視頻的一幀,不存在半幀說法。但可以獲取音頻的若干幀。

          說明①:av_read_frame()函數(shù)是ffmpeg新型的用法,就用法之所以被拋棄,就是因?yàn)橐郧矮@取的數(shù)據(jù)可能不是完整的,而av_read_frame()保證了視頻數(shù)據(jù)一幀的完整性。

          說明②:查看API的改變可以看到,從2012-03-20開始,Deprecate av_read_packet(), use av_read_frame()

          返回流的下一幀。
          *此函數(shù)返回存儲在文件中的內(nèi)容,但不驗(yàn)證解碼器是否有有效幀。
          它將把文件中存儲的內(nèi)容拆分為幀,并為每個調(diào)用返回一個幀。
          它不會省略有效幀之間的無效數(shù)據(jù),以便給解碼器最大可能的解碼信息。
          如果pkt->buf為NULL,那么直到下一個av_read_frame()或直到avformat_close_input(),包都是有效的。
          否則數(shù)據(jù)包將無限期有效。在這兩種情況下,當(dāng)不再需要包時(shí),必須使用av_free_packet釋放包。
          對于視頻,數(shù)據(jù)包只包含一幀。
          對于音頻,如果每個幀具有已知的固定大小(例如PCM或ADPCM數(shù)據(jù)),則它包含整數(shù)幀數(shù)。
          如果音頻幀有一個可變的大小(例如MPEG音頻),那么它包含一幀。
          在AVStream中,pkt->pts、pkt->dts和pkt->持續(xù)時(shí)間總是被設(shè)置為恰當(dāng)?shù)闹怠?br>time_base單元(猜測格式是否不能提供它們)。
          如果視頻格式為B-frames,pkt->pts可以是AV_NOPTS_VALUE,所以如果不解壓縮有效負(fù)載,最好依賴pkt->dts。
          int?av_read_frame(AVFormatContext?*s,?AVPacket?*pkt);

          參數(shù)說明

          *AVFormatContext s :文件格式上下文,輸入的AVFormatContext

          *AVPacket pkt:這個值不能傳NULL,必須是一個空間,輸出的AVPacket

          返回值:return 0 is OK, <0 on error or end of file

          av_read_frame()函數(shù)源碼位于 lib/avformat/utils.c

          int?av_read_frame(AVFormatContext?*s,?AVPacket?*pkt)
          {
          ????const?int?genpts?=?s->flags?&?AVFMT_FLAG_GENPTS;
          ????int?eof?=?0;
          ????int?ret;
          ????AVStream?*st;

          ????if?(!genpts)?{
          ????????ret?=?s->internal->packet_buffer
          ????????????????ff_packet_list_get(&s->internal->packet_buffer,
          ????????????????????????????????????????&s->internal->packet_buffer_end,?pkt)
          ??????????????:?read_frame_internal(s,?pkt);
          ????????if?(ret?0)
          ????????????return?ret;
          ????????goto?return_packet;
          ????}

          ????for?(;;)?{
          ????????AVPacketList?*pktl?=?s->internal->packet_buffer;

          ????????if?(pktl)?{
          ????????????AVPacket?*next_pkt?=?&pktl->pkt;

          ????????????if?(next_pkt->dts?!=?AV_NOPTS_VALUE)?{
          ????????????????int?wrap_bits?=?s->streams[next_pkt->stream_index]->pts_wrap_bits;
          ????????????????//?last?dts?seen?for?this?stream.?if?any?of?packets?following
          ????????????????//?current?one?had?no?dts,?we?will?set?this?to?AV_NOPTS_VALUE.
          ????????????????int64_t?last_dts?=?next_pkt->dts;
          ????????????????av_assert2(wrap_bits?<=?64);
          ????????????????while?(pktl?&&?next_pkt->pts?==?AV_NOPTS_VALUE)?{
          ????????????????????if?(pktl->pkt.stream_index?==?next_pkt->stream_index?&&
          ????????????????????????av_compare_mod(next_pkt->dts,?pktl->pkt.dts,?2ULL?<1))?0)?{
          ????????????????????????if?(av_compare_mod(pktl->pkt.pts,?pktl->pkt.dts,?2ULL?<1)))?{
          ????????????????????????????//?not?B-frame
          ????????????????????????????next_pkt->pts?=?pktl->pkt.dts;
          ????????????????????????}
          ????????????????????????if?(last_dts?!=?AV_NOPTS_VALUE)?{
          ????????????????????????????//?Once?last?dts?was?set?to?AV_NOPTS_VALUE,?we?don't?change?it.
          ????????????????????????????last_dts?=?pktl->pkt.dts;
          ????????????????????????}
          ????????????????????}
          ????????????????????pktl?=?pktl->next;
          ????????????????}
          ????????????????if?(eof?&&?next_pkt->pts?==?AV_NOPTS_VALUE?&&?last_dts?!=?AV_NOPTS_VALUE)?{
          ????????????????????//?Fixing?the?last?reference?frame?had?none?pts?issue?(For?MXF?etc).
          ????????????????????//?We?only?do?this?when
          ????????????????????//?1.?eof.
          ????????????????????//?2.?we?are?not?able?to?resolve?a?pts?value?for?current?packet.
          ????????????????????//?3.?the?packets?for?this?stream?at?the?end?of?the?files?had?valid?dts.
          ????????????????????next_pkt->pts?=?last_dts?+?next_pkt->duration;
          ????????????????}
          ????????????????pktl?=?s->internal->packet_buffer;
          ????????????}

          ????????????/*?read?packet?from?packet?buffer,?if?there?is?data?*/
          ????????????st?=?s->streams[next_pkt->stream_index];
          ????????????if?(!(next_pkt->pts?==?AV_NOPTS_VALUE?&&?st->discard???????????????????next_pkt->dts?!=?AV_NOPTS_VALUE?&&?!eof))?{
          ????????????????ret?=?ff_packet_list_get(&s->internal->packet_buffer,
          ???????????????????????????????????????????????&s->internal->packet_buffer_end,?pkt);
          ????????????????goto?return_packet;
          ????????????}
          ????????}

          ????????ret?=?read_frame_internal(s,?pkt);
          ????????if?(ret?0)?{
          ????????????if?(pktl?&&?ret?!=?AVERROR(EAGAIN))?{
          ????????????????eof?=?1;
          ????????????????continue;
          ????????????}?else
          ????????????????return?ret;
          ????????}

          ????????ret?=?ff_packet_list_put(&s->internal->packet_buffer,
          ?????????????????????????????????&s->internal->packet_buffer_end,
          ?????????????????????????????????pkt,?FF_PACKETLIST_FLAG_REF_PACKET);
          ????????av_packet_unref(pkt);
          ????????if?(ret?0)
          ????????????return?ret;
          ????}

          return_packet:

          ????st?=?s->streams[pkt->stream_index];
          ????if?((s->iformat->flags?&?AVFMT_GENERIC_INDEX)?&&?pkt->flags?&?AV_PKT_FLAG_KEY)?{
          ????????ff_reduce_index(s,?st->index);
          ????????av_add_index_entry(st,?pkt->pos,?pkt->dts,?0,?0,?AVINDEX_KEYFRAME);
          ????}

          ????if?(is_relative(pkt->dts))
          ????????pkt->dts?-=?RELATIVE_TS_BASE;
          ????if?(is_relative(pkt->pts))
          ????????pkt->pts?-=?RELATIVE_TS_BASE;

          ????return?ret;
          }

          RTC 技術(shù)知識體系

          幾種直播流媒體協(xié)議

          RTSP協(xié)議


          以上,便是今天的分享,希望大家喜歡,覺得內(nèi)容不錯的,歡迎「分享」「」或者點(diǎn)擊「在看」支持,謝謝各位。

          瀏覽 40
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天躁夜夜躁狂躁2022 | 日本巨乳一级A片 | 丁香色播五月 | 无码免费一区二区三区 | 成人毛片网站视频 |