Blame view

ffmpeg-4.2.2/libavcodec/av1_parse.c 3.11 KB
aac5773f   hucm   功能基本完成,接口待打磨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  /*
   * AV1 common parsing code
   *
   * This file is part of FFmpeg.
   *
   * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
  #include "config.h"
  
  #include "libavutil/mem.h"
  
  #include "av1.h"
  #include "av1_parse.h"
  #include "bytestream.h"
  
  int ff_av1_extract_obu(AV1OBU *obu, const uint8_t *buf, int length, void *logctx)
  {
      int64_t obu_size;
      int start_pos, type, temporal_id, spatial_id;
      int len;
  
      len = parse_obu_header(buf, length, &obu_size, &start_pos,
                             &type, &temporal_id, &spatial_id);
      if (len < 0)
          return len;
  
      obu->type        = type;
      obu->temporal_id = temporal_id;
      obu->spatial_id  = spatial_id;
  
      obu->data     = buf + start_pos;
      obu->size     = obu_size;
      obu->raw_data = buf;
      obu->raw_size = len;
  
      av_log(logctx, AV_LOG_DEBUG,
             "obu_type: %d, temporal_id: %d, spatial_id: %d, payload size: %d\n",
             obu->type, obu->temporal_id, obu->spatial_id, obu->size);
  
      return len;
  }
  
  int ff_av1_packet_split(AV1Packet *pkt, const uint8_t *buf, int length, void *logctx)
  {
      GetByteContext bc;
      int ret, consumed;
  
      bytestream2_init(&bc, buf, length);
      pkt->nb_obus = 0;
  
      while (bytestream2_get_bytes_left(&bc) > 0) {
          AV1OBU *obu;
  
          if (pkt->obus_allocated < pkt->nb_obus + 1) {
              int new_size = pkt->obus_allocated + 1;
              AV1OBU *tmp = av_realloc_array(pkt->obus, new_size, sizeof(*tmp));
              if (!tmp)
                  return AVERROR(ENOMEM);
  
              pkt->obus = tmp;
              memset(pkt->obus + pkt->obus_allocated, 0,
                     (new_size - pkt->obus_allocated) * sizeof(*tmp));
              pkt->obus_allocated = new_size;
          }
          obu = &pkt->obus[pkt->nb_obus];
  
          consumed = ff_av1_extract_obu(obu, bc.buffer, bytestream2_get_bytes_left(&bc), logctx);
          if (consumed < 0)
              return consumed;
  
          bytestream2_skip(&bc, consumed);
  
          obu->size_bits = get_obu_bit_length(obu->data, obu->size, obu->type);
  
          if (obu->size_bits < 0 || (!obu->size_bits && obu->type != AV1_OBU_TEMPORAL_DELIMITER)) {
              av_log(logctx, AV_LOG_ERROR, "Invalid OBU of type %d, skipping.\n", obu->type);
              continue;
          }
  
          pkt->nb_obus++;
  
          ret = init_get_bits(&obu->gb, obu->data, obu->size_bits);
          if (ret < 0)
              return ret;
      }
  
      return 0;
  }
  
  void ff_av1_packet_uninit(AV1Packet *pkt)
  {
      av_freep(&pkt->obus);
      pkt->obus_allocated = 0;
  }