Blame view

ffmpeg-4.2.2/libavcodec/hevc_ps_enc.c 4.19 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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
  /*
   * HEVC Parameter Set encoding
   *
   * 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 "golomb.h"
  #include "hevc_ps.h"
  #include "put_bits.h"
  
  static void write_ptl_layer(PutBitContext *pb, PTLCommon *ptl)
  {
      int i;
  
      put_bits(pb, 2, ptl->profile_space);
      put_bits(pb, 1, ptl->tier_flag);
      put_bits(pb, 5, ptl->profile_idc);
      for (i = 0; i < 32; i++)
          put_bits(pb, 1, ptl->profile_compatibility_flag[i]);
      put_bits(pb, 1, ptl->progressive_source_flag);
      put_bits(pb, 1, ptl->interlaced_source_flag);
      put_bits(pb, 1, ptl->non_packed_constraint_flag);
      put_bits(pb, 1, ptl->frame_only_constraint_flag);
      put_bits32(pb, 0);   // reserved
      put_bits(pb, 12, 0); // reserved
  }
  
  static void write_ptl(PutBitContext *pb, PTL *ptl, int max_num_sub_layers)
  {
      int i;
  
      write_ptl_layer(pb, &ptl->general_ptl);
      put_bits(pb, 8, ptl->general_ptl.level_idc);
  
      for (i = 0; i < max_num_sub_layers - 1; i++) {
          put_bits(pb, 1, ptl->sub_layer_profile_present_flag[i]);
          put_bits(pb, 1, ptl->sub_layer_level_present_flag[i]);
      }
  
      if (max_num_sub_layers > 1)
          for (i = max_num_sub_layers - 1; i < 8; i++)
              put_bits(pb, 2, 0); // reserved
  
      for (i = 0; i < max_num_sub_layers - 1; i++) {
          if (ptl->sub_layer_profile_present_flag[i])
              write_ptl_layer(pb, &ptl->sub_layer_ptl[i]);
          if (ptl->sub_layer_level_present_flag[i])
              put_bits(pb, 8, ptl->sub_layer_ptl[i].level_idc);
      }
  }
  
  int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id,
                             uint8_t *buf, int buf_size)
  {
      PutBitContext pb;
      int i, data_size;
  
      init_put_bits(&pb, buf, buf_size);
      put_bits(&pb,  4, id);
      put_bits(&pb,  2, 3);                               // reserved
      put_bits(&pb,  6, vps->vps_max_layers - 1);
      put_bits(&pb,  3, vps->vps_max_sub_layers - 1);
      put_bits(&pb,  1, vps->vps_temporal_id_nesting_flag);
      put_bits(&pb, 16, 0xffff);                          // reserved
  
      write_ptl(&pb, &vps->ptl, vps->vps_max_sub_layers);
  
      put_bits(&pb, 1, vps->vps_sub_layer_ordering_info_present_flag);
      for (i = vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_layers - 1;
           i < vps->vps_max_sub_layers; i++) {
          set_ue_golomb(&pb, vps->vps_max_dec_pic_buffering[i] - 1);
          set_ue_golomb(&pb, vps->vps_num_reorder_pics[i]);
          set_ue_golomb(&pb, vps->vps_max_latency_increase[i] + 1);
      }
  
      put_bits(&pb, 6, vps->vps_max_layer_id);
      set_ue_golomb(&pb, vps->vps_num_layer_sets - 1);
  
      if (vps->vps_num_layer_sets > 1) {
          avpriv_report_missing_feature(NULL, "Writing layer_id_included_flag");
          return AVERROR_PATCHWELCOME;
      }
  
      put_bits(&pb, 1, vps->vps_timing_info_present_flag);
      if (vps->vps_timing_info_present_flag) {
          put_bits32(&pb, vps->vps_num_units_in_tick);
          put_bits32(&pb, vps->vps_time_scale);
          put_bits(&pb, 1, vps->vps_poc_proportional_to_timing_flag);
          if (vps->vps_poc_proportional_to_timing_flag)
              set_ue_golomb(&pb, vps->vps_num_ticks_poc_diff_one - 1);
  
          set_ue_golomb(&pb, vps->vps_num_hrd_parameters);
          if (vps->vps_num_hrd_parameters) {
              avpriv_report_missing_feature(NULL, "Writing HRD parameters");
              return AVERROR_PATCHWELCOME;
          }
      }
  
      put_bits(&pb, 1, 0);    // extension flag
  
      put_bits(&pb, 1, 1);    // stop bit
      avpriv_align_put_bits(&pb);
  
      data_size = put_bits_count(&pb) / 8;
      flush_put_bits(&pb);
  
      return data_size;
  }