FFmpeg  4.2.2
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 <stdbool.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #if HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 #if HAVE_IO_H
36 #include <io.h>
37 #endif
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 
42 #include "libavcodec/avcodec.h"
43 #include "libavutil/pixdesc.h"
44 #include "libavutil/hash.h"
45 #include "libavutil/bswap.h"
46 
47 static int header = 0;
48 
50  AVPacket *pkt)
51 {
52  static uint64_t frame_cnt = 0;
53  int ret;
54 
55  ret = avcodec_send_packet(dec_ctx, pkt);
56  if (ret < 0) {
57  fprintf(stderr, "Error sending a packet for decoding: %s\n", av_err2str(ret));
58  return ret;
59  }
60 
61  while (ret >= 0) {
62  const AVPixFmtDescriptor *desc;
63  char sum[AV_HASH_MAX_SIZE * 2 + 1];
64  struct AVHashContext *hash;
65 
66  ret = avcodec_receive_frame(dec_ctx, frame);
67  if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
68  return 0;
69  } else if (ret < 0) {
70  fprintf(stderr, "Error during decoding: %s\n", av_err2str(ret));
71  return ret;
72  }
73 
74  if (!header) {
75  printf(
76  "#format: frame checksums\n"
77  "#version: 2\n"
78  "#hash: MD5\n"
79  "#tb 0: 1/30\n"
80  "#media_type 0: video\n"
81  "#codec_id 0: rawvideo\n"
82  "#dimensions 0: 352x288\n"
83  "#sar 0: 128/117\n"
84  "#stream#, dts, pts, duration, size, hash\n");
85  header = 1;
86  }
87  desc = av_pix_fmt_desc_get(dec_ctx->pix_fmt);
88  if ((ret = av_hash_alloc(&hash, "md5")) < 0) {
89  return ret;
90  }
91  av_hash_init(hash);
92 
93  for (int i = 0; i < frame->height; i++)
94  av_hash_update(hash, &frame->data[0][i * frame->linesize[0]], frame->width);
95  for (int i = 0; i < frame->height >> desc->log2_chroma_h; i++)
96  av_hash_update(hash, &frame->data[1][i * frame->linesize[1]], frame->width >> desc->log2_chroma_w);
97  for (int i = 0; i < frame->height >> desc->log2_chroma_h; i++)
98  av_hash_update(hash, &frame->data[2][i * frame->linesize[2]], frame->width >> desc->log2_chroma_w);
99 
100  av_hash_final_hex(hash, sum, av_hash_get_size(hash) * 2 + 1);
101  printf("0, %10"PRId64", %10"PRId64", 1, %8d, %s\n",
102  frame_cnt, frame_cnt,
103  (frame->width * frame->height + 2 * (frame->height >> desc->log2_chroma_h) * (frame->width >> desc->log2_chroma_w)), sum);
104  frame_cnt += 1;
105  av_hash_freep(&hash);
106  }
107  return 0;
108 }
109 
110 int main(int argc, char **argv)
111 {
112  const AVCodec *codec = NULL;
113  AVCodecContext *c = NULL;
114  AVFrame *frame = NULL;
115  unsigned int threads;
116  AVPacket *pkt;
117  FILE *file = NULL;
118  char * nal = NULL;
119  int nals = 0, ret = 0;
120  char *p;
121 
122  if (argc < 3) {
123  fprintf(stderr, "Usage: %s <threads> <input file>\n", argv[0]);
124  return -1;
125  }
126 
127  if (!(threads = strtoul(argv[1], NULL, 0)))
128  threads = 1;
129  else if (threads > MAX_SLICES)
130  threads = MAX_SLICES;
131 
132 #ifdef _WIN32
133  setmode(fileno(stdout), O_BINARY);
134 #endif
135 
136  if (!(pkt = av_packet_alloc())) {
137  return -1;
138  }
139 
140  nal = av_malloc(MAX_SLICES * UINT16_MAX + AV_INPUT_BUFFER_PADDING_SIZE);
141  if (!nal)
142  goto err;
143  p = nal;
144 
145  if (!(codec = avcodec_find_decoder(AV_CODEC_ID_H264))) {
146  fprintf(stderr, "Codec not found\n");
147  ret = -1;
148  goto err;
149  }
150 
151  if (!(c = avcodec_alloc_context3(codec))) {
152  fprintf(stderr, "Could not allocate video codec context\n");
153  ret = -1;
154  goto err;
155  }
156 
157  c->width = 352;
158  c->height = 288;
159 
162  c->thread_count = threads;
163 
164  if ((ret = avcodec_open2(c, codec, NULL)) < 0) {
165  fprintf(stderr, "Could not open codec\n");
166  goto err;
167  }
168 
169 #if HAVE_THREADS
171  fprintf(stderr, "Couldn't activate slice threading: %d\n", c->active_thread_type);
172  ret = -1;
173  goto err;
174  }
175 #else
176  fprintf(stderr, "WARN: not using threads, only checking decoding slice NALUs\n");
177 #endif
178 
179  if (!(frame = av_frame_alloc())) {
180  fprintf(stderr, "Could not allocate video frame\n");
181  ret = -1;
182  goto err;
183  }
184 
185  if (!(file = fopen(argv[2], "rb"))) {
186  fprintf(stderr, "Couldn't open NALU file: %s\n", argv[2]);
187  ret = -1;
188  goto err;
189  }
190 
191  while(1) {
192  uint16_t size = 0;
193  size_t ret = fread(&size, 1, sizeof(uint16_t), file);
194  if (ret != sizeof(uint16_t))
195  break;
196 
197  size = av_be2ne16(size);
198  ret = fread(p, 1, size, file);
199  if (ret != size) {
200  perror("Couldn't read data");
201  goto err;
202  }
203  p += ret;
204 
205  if (++nals >= threads) {
206  int decret = 0;
207  pkt->data = nal;
208  pkt->size = p - nal;
209  if ((decret = decode(c, frame, pkt)) < 0) {
210  goto err;
211  }
212  memset(nal, 0, MAX_SLICES * UINT16_MAX + AV_INPUT_BUFFER_PADDING_SIZE);
213  nals = 0;
214  p = nal;
215  }
216  }
217 
218  if (nals) {
219  pkt->data = nal;
220  pkt->size = p - nal;
221  if ((ret = decode(c, frame, pkt)) < 0) {
222  goto err;
223  }
224  }
225 
226  ret = decode(c, frame, NULL);
227 
228 err:
229  if (nal)
230  av_free(nal);
231  if (file)
232  fclose(file);
233  av_frame_free(&frame);
235  av_packet_free(&pkt);
236 
237  return ret;
238 }
#define NULL
Definition: coverity.c:32
int size
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
#define O_BINARY
const char * desc
Definition: nvenc.c:68
int size
Definition: avcodec.h:1478
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
#define AV_CODEC_FLAG2_CHUNKS
Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries...
Definition: avcodec.h:942
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3481
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:62
#define av_malloc(s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:189
Generic hashing API.
static AVFrame * frame
uint8_t * data
Definition: avcodec.h:1477
#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:259
static int decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt)
int width
Definition: frame.h:353
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:202
int active_thread_type
Which multithreading methods are in use by the codec.
Definition: avcodec.h:2843
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Return decoded output data from a decoder.
Definition: decode.c:740
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:156
int width
picture width / height.
Definition: avcodec.h:1738
#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:2836
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
Definition: avcodec.h:2824
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Supply raw packet data as input to a decoder.
Definition: decode.c:677
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:171
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
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:1565
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:890
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:548
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
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:790
#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:51
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:1652
int height
Definition: frame.h:353
This structure stores compressed data.
Definition: avcodec.h:1454
int thread_type
Which multithreading methods to use.
Definition: avcodec.h:2834
#define MAX_SLICES