FFmpeg  4.3.7
api-h264-slice-test.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001 Fabrice Bellard
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #define MAX_SLICES 8
24 
25 #include "config.h"
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #if HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 #if HAVE_IO_H
35 #include <io.h>
36 #endif
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 
41 #include "libavcodec/avcodec.h"
42 #include "libavutil/pixdesc.h"
43 #include "libavutil/hash.h"
44 #include "libavutil/bswap.h"
45 
46 static int header = 0;
47 
49  AVPacket *pkt)
50 {
51  static uint64_t frame_cnt = 0;
52  int ret;
53 
54  ret = avcodec_send_packet(dec_ctx, pkt);
55  if (ret < 0) {
56  fprintf(stderr, "Error sending a packet for decoding: %s\n", av_err2str(ret));
57  return ret;
58  }
59 
60  while (ret >= 0) {
61  const AVPixFmtDescriptor *desc;
62  char sum[AV_HASH_MAX_SIZE * 2 + 1];
63  struct AVHashContext *hash;
64 
65  ret = avcodec_receive_frame(dec_ctx, frame);
66  if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
67  return 0;
68  } else if (ret < 0) {
69  fprintf(stderr, "Error during decoding: %s\n", av_err2str(ret));
70  return ret;
71  }
72 
73  if (!header) {
74  printf(
75  "#format: frame checksums\n"
76  "#version: 2\n"
77  "#hash: MD5\n"
78  "#tb 0: 1/30\n"
79  "#media_type 0: video\n"
80  "#codec_id 0: rawvideo\n"
81  "#dimensions 0: 352x288\n"
82  "#sar 0: 128/117\n"
83  "#stream#, dts, pts, duration, size, hash\n");
84  header = 1;
85  }
86  desc = av_pix_fmt_desc_get(dec_ctx->pix_fmt);
87  if ((ret = av_hash_alloc(&hash, "md5")) < 0) {
88  return ret;
89  }
90  av_hash_init(hash);
91 
92  for (int i = 0; i < frame->height; i++)
93  av_hash_update(hash, &frame->data[0][i * frame->linesize[0]], frame->width);
94  for (int i = 0; i < frame->height >> desc->log2_chroma_h; i++)
95  av_hash_update(hash, &frame->data[1][i * frame->linesize[1]], frame->width >> desc->log2_chroma_w);
96  for (int i = 0; i < frame->height >> desc->log2_chroma_h; i++)
97  av_hash_update(hash, &frame->data[2][i * frame->linesize[2]], frame->width >> desc->log2_chroma_w);
98 
99  av_hash_final_hex(hash, sum, av_hash_get_size(hash) * 2 + 1);
100  printf("0, %10"PRId64", %10"PRId64", 1, %8d, %s\n",
101  frame_cnt, frame_cnt,
102  (frame->width * frame->height + 2 * (frame->height >> desc->log2_chroma_h) * (frame->width >> desc->log2_chroma_w)), sum);
103  frame_cnt += 1;
104  av_hash_freep(&hash);
105  }
106  return 0;
107 }
108 
109 int main(int argc, char **argv)
110 {
111  const AVCodec *codec = NULL;
112  AVCodecContext *c = NULL;
113  AVFrame *frame = NULL;
114  unsigned int threads;
115  AVPacket *pkt;
116  FILE *file = NULL;
117  char * nal = NULL;
118  int nals = 0, ret = 0;
119  char *p;
120 
121  if (argc < 3) {
122  fprintf(stderr, "Usage: %s <threads> <input file>\n", argv[0]);
123  return -1;
124  }
125 
126  if (!(threads = strtoul(argv[1], NULL, 0)))
127  threads = 1;
128  else if (threads > MAX_SLICES)
129  threads = MAX_SLICES;
130 
131 #ifdef _WIN32
132  setmode(fileno(stdout), O_BINARY);
133 #endif
134 
135  if (!(pkt = av_packet_alloc())) {
136  return -1;
137  }
138 
139  nal = av_malloc(MAX_SLICES * UINT16_MAX + AV_INPUT_BUFFER_PADDING_SIZE);
140  if (!nal)
141  goto err;
142  p = nal;
143 
144  if (!(codec = avcodec_find_decoder(AV_CODEC_ID_H264))) {
145  fprintf(stderr, "Codec not found\n");
146  ret = -1;
147  goto err;
148  }
149 
150  if (!(c = avcodec_alloc_context3(codec))) {
151  fprintf(stderr, "Could not allocate video codec context\n");
152  ret = -1;
153  goto err;
154  }
155 
156  c->width = 352;
157  c->height = 288;
158 
161  c->thread_count = threads;
162 
163  if ((ret = avcodec_open2(c, codec, NULL)) < 0) {
164  fprintf(stderr, "Could not open codec\n");
165  goto err;
166  }
167 
168 #if HAVE_THREADS
170  fprintf(stderr, "Couldn't activate slice threading: %d\n", c->active_thread_type);
171  ret = -1;
172  goto err;
173  }
174 #else
175  fprintf(stderr, "WARN: not using threads, only checking decoding slice NALUs\n");
176 #endif
177 
178  if (!(frame = av_frame_alloc())) {
179  fprintf(stderr, "Could not allocate video frame\n");
180  ret = -1;
181  goto err;
182  }
183 
184  if (!(file = fopen(argv[2], "rb"))) {
185  fprintf(stderr, "Couldn't open NALU file: %s\n", argv[2]);
186  ret = -1;
187  goto err;
188  }
189 
190  while(1) {
191  uint16_t size = 0;
192  size_t ret = fread(&size, 1, sizeof(uint16_t), file);
193  if (ret != sizeof(uint16_t))
194  break;
195 
196  size = av_be2ne16(size);
197  ret = fread(p, 1, size, file);
198  if (ret != size) {
199  perror("Couldn't read data");
200  goto err;
201  }
202  p += ret;
203 
204  if (++nals >= threads) {
205  int decret = 0;
206  pkt->data = nal;
207  pkt->size = p - nal;
208  if ((decret = decode(c, frame, pkt)) < 0) {
209  goto err;
210  }
211  memset(nal, 0, MAX_SLICES * UINT16_MAX + AV_INPUT_BUFFER_PADDING_SIZE);
212  nals = 0;
213  p = nal;
214  }
215  }
216 
217  if (nals) {
218  pkt->data = nal;
219  pkt->size = p - nal;
220  if ((ret = decode(c, frame, pkt)) < 0) {
221  goto err;
222  }
223  }
224 
225  ret = decode(c, frame, NULL);
226 
227 err:
228  if (nal)
229  av_free(nal);
230  if (file)
231  fclose(file);
232  av_frame_free(&frame);
234  av_packet_free(&pkt);
235 
236  return ret;
237 }
#define NULL
Definition: coverity.c:32
int size
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2549
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
#define O_BINARY
const char * desc
Definition: nvenc.c:79
int size
Definition: packet.h:356
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:736
#define AV_CODEC_FLAG2_CHUNKS
Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries...
Definition: avcodec.h:367
static AVPacket pkt
AVCodec.
Definition: codec.h:190
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
#define AV_HASH_MAX_SIZE
Maximum value that av_hash_get_size() will currently return.
Definition: hash.h:157
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:64
#define av_malloc(s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
Generic hashing API.
static AVFrame * frame
uint8_t * data
Definition: packet.h:355
#define AVERROR_EOF
End of file.
Definition: error.h:55
uint8_t hash[HASH_SIZE]
Definition: movenc.c:57
void av_hash_init(AVHashContext *ctx)
Initialize or reset a hash context.
Definition: hash.c:137
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
static int decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt)
int width
Definition: frame.h:358
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
int active_thread_type
Which multithreading methods are in use by the codec.
Definition: avcodec.h:1804
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Return decoded output data from a decoder.
Definition: decode.c:649
int av_hash_alloc(AVHashContext **ctx, const char *name)
Allocate a hash context for the algorithm specified by name.
Definition: hash.c:100
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:157
int width
picture width / height.
Definition: avcodec.h:699
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:119
#define FF_THREAD_SLICE
Decode more than one part of a single frame at once.
Definition: avcodec.h:1797
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
Definition: avcodec.h:1785
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Supply raw packet data as input to a decoder.
Definition: decode.c:586
Libavcodec external API header.
int av_hash_get_size(const AVHashContext *ctx)
Definition: hash.c:95
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer...
Definition: options.c:172
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:331
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
main external API structure.
Definition: avcodec.h:526
void av_hash_update(AVHashContext *ctx, const uint8_t *src, int len)
Update a hash context with additional data.
Definition: hash.c:159
void av_hash_freep(AVHashContext **ctx)
Free hash context and set hash context pointer to NULL.
Definition: hash.c:238
int main(int argc, char **argv)
void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size)
Finalize a hash context and store the hexadecimal representation of the actual hash value as a string...
Definition: hash.c:215
byte swapping routines
static int header
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
Definition: utils.c:571
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:919
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:314
static double c[64]
static AVCodecContext * dec_ctx
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:215
#define av_be2ne16(x)
Definition: bswap.h:92
#define av_free(p)
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:53
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:613
int height
Definition: frame.h:358
This structure stores compressed data.
Definition: packet.h:332
int thread_type
Which multithreading methods to use.
Definition: avcodec.h:1795
#define MAX_SLICES