FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 // ./fate 2 ./crew_cif out.y4m
26 
27 #include "config.h"
28 
29 #include <stdbool.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #if HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37 #if HAVE_IO_H
38 #include <io.h>
39 #endif
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <fcntl.h>
43 
44 #include "libavformat/network.h"
45 #include "libavcodec/avcodec.h"
46 #include "libavutil/pixdesc.h"
47 #include "libavutil/hash.h"
48 
49 static int header = 0;
50 
52  AVPacket *pkt)
53 {
54  static uint64_t frame_cnt = 0;
55  int ret;
56 
57  ret = avcodec_send_packet(dec_ctx, pkt);
58  if (ret < 0) {
59  fprintf(stderr, "Error sending a packet for decoding: %s\n", av_err2str(ret));
60  return ret;
61  }
62 
63  while (ret >= 0) {
64  const AVPixFmtDescriptor *desc;
65  char sum[AV_HASH_MAX_SIZE * 2 + 1];
66  struct AVHashContext *hash;
67 
68  ret = avcodec_receive_frame(dec_ctx, frame);
69  if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
70  return 0;
71  } else if (ret < 0) {
72  fprintf(stderr, "Error during decoding: %s\n", av_err2str(ret));
73  return ret;
74  }
75 
76  if (!header) {
77  printf(
78  "#format: frame checksums\n"
79  "#version: 2\n"
80  "#hash: MD5\n"
81  "#tb 0: 1/30\n"
82  "#media_type 0: video\n"
83  "#codec_id 0: rawvideo\n"
84  "#dimensions 0: 352x288\n"
85  "#sar 0: 128/117\n"
86  "#stream#, dts, pts, duration, size, hash\n");
87  header = 1;
88  }
89  desc = av_pix_fmt_desc_get(dec_ctx->pix_fmt);
90  if ((ret = av_hash_alloc(&hash, "md5")) < 0) {
91  return ret;
92  }
93  av_hash_init(hash);
94 
95  for (int i = 0; i < frame->height; i++)
96  av_hash_update(hash, &frame->data[0][i * frame->linesize[0]], frame->width);
97  for (int i = 0; i < frame->height >> desc->log2_chroma_h; i++)
98  av_hash_update(hash, &frame->data[1][i * frame->linesize[1]], frame->width >> desc->log2_chroma_w);
99  for (int i = 0; i < frame->height >> desc->log2_chroma_h; i++)
100  av_hash_update(hash, &frame->data[2][i * frame->linesize[2]], frame->width >> desc->log2_chroma_w);
101 
102  av_hash_final_hex(hash, sum, av_hash_get_size(hash) * 2 + 1);
103  printf("0, %10"PRId64", %10"PRId64", 1, %8d, %s\n",
104  frame_cnt, frame_cnt,
105  (frame->width * frame->height + 2 * (frame->height >> desc->log2_chroma_h) * (frame->width >> desc->log2_chroma_w)), sum);
106  frame_cnt += 1;
107  av_hash_freep(&hash);
108  }
109  return 0;
110 }
111 
112 int main(int argc, char **argv)
113 {
114  const AVCodec *codec = NULL;
115  AVCodecContext *c = NULL;
116  AVFrame *frame = NULL;
117  unsigned int threads;
118  AVPacket *pkt;
119  FILE *file = NULL;
120  char nal[MAX_SLICES * UINT16_MAX + AV_INPUT_BUFFER_PADDING_SIZE];
121  int nals = 0, ret = 0;
122  char *p = nal;
123 
124  if (argc < 4) {
125  fprintf(stderr, "Usage: %s <threads> <input file> <output file>\n", argv[0]);
126  return -1;
127  }
128 
129  if (!(threads = strtoul(argv[1], NULL, 0)))
130  threads = 1;
131  else if (threads > MAX_SLICES)
132  threads = MAX_SLICES;
133 
134 #ifdef _WIN32
135  setmode(fileno(stdout), O_BINARY);
136 #endif
137 
138  if (!(pkt = av_packet_alloc())) {
139  return -1;
140  }
141 
142  if (!(codec = avcodec_find_decoder(AV_CODEC_ID_H264))) {
143  fprintf(stderr, "Codec not found\n");
144  ret = -1;
145  goto err;
146  }
147 
148  if (!(c = avcodec_alloc_context3(codec))) {
149  fprintf(stderr, "Could not allocate video codec context\n");
150  ret = -1;
151  goto err;
152  }
153 
154  c->width = 352;
155  c->height = 288;
156 
159  c->thread_count = threads;
160 
161  if ((ret = avcodec_open2(c, codec, NULL)) < 0) {
162  fprintf(stderr, "Could not open codec\n");
163  goto err;
164  }
165 
166 #if HAVE_THREADS
168  fprintf(stderr, "Couldn't activate slice threading: %d\n", c->active_thread_type);
169  ret = -1;
170  goto err;
171  }
172 #else
173  fprintf(stderr, "WARN: not using threads, only checking decoding slice NALUs\n");
174 #endif
175 
176  if (!(frame = av_frame_alloc())) {
177  fprintf(stderr, "Could not allocate video frame\n");
178  ret = -1;
179  goto err;
180  }
181 
182  if (!(file = fopen(argv[2], "rb"))) {
183  fprintf(stderr, "Couldn't open NALU file: %s\n", argv[2]);
184  ret = -1;
185  goto err;
186  }
187 
188  while(1) {
189  uint16_t size = 0;
190  size_t ret = fread(&size, 1, sizeof(uint16_t), file);
191  if (ret != sizeof(uint16_t))
192  break;
193 
194  size = ntohs(size);
195  ret = fread(p, 1, size, file);
196  if (ret != size) {
197  perror("Couldn't read data");
198  goto err;
199  }
200  p += ret;
201 
202  if (++nals >= threads) {
203  int decret = 0;
204  pkt->data = nal;
205  pkt->size = p - nal;
206  if ((decret = decode(c, frame, pkt)) < 0) {
207  goto err;
208  }
209  memset(nal, 0, MAX_SLICES * UINT16_MAX + AV_INPUT_BUFFER_PADDING_SIZE);
210  nals = 0;
211  p = nal;
212  }
213  }
214 
215  if (nals) {
216  pkt->data = nal;
217  pkt->size = p - nal;
218  if ((ret = decode(c, frame, pkt)) < 0) {
219  goto err;
220  }
221  }
222 
223  ret = decode(c, frame, NULL);
224 
225 err:
226  if (file)
227  fclose(file);
228  av_frame_free(&frame);
230  av_packet_free(&pkt);
231 
232  return ret;
233 }
#define NULL
Definition: coverity.c:32
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2446
This structure describes decoded (raw) audio or video data.
Definition: frame.h:226
#define O_BINARY
const char * desc
Definition: nvenc.c:65
int size
Definition: avcodec.h:1446
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1743
#define AV_CODEC_FLAG2_CHUNKS
Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries...
Definition: avcodec.h:929
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3424
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
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:1445
#define AVERROR_EOF
End of file.
Definition: error.h:55
ptrdiff_t size
Definition: opengl_enc.c:101
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
static int decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt)
int width
Definition: frame.h:284
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:2804
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:1706
#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:2797
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
Definition: avcodec.h:2785
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:257
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:1533
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:880
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
static int header
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
Definition: utils.c:538
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:240
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:782
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:1620
int height
Definition: frame.h:284
This structure stores compressed data.
Definition: avcodec.h:1422
int thread_type
Which multithreading methods to use.
Definition: avcodec.h:2795
#define MAX_SLICES