FFmpeg  4.4.6
api-h264-test.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Ludmila Glinskih
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 /**
24  * H264 codec test.
25  */
26 
27 #include "libavutil/adler32.h"
28 #include "libavcodec/avcodec.h"
29 #include "libavformat/avformat.h"
30 #include "libavutil/imgutils.h"
31 #include "libavutil/timestamp.h"
32 
33 static int video_decode_example(const char *input_filename)
34 {
35  AVCodec *codec = NULL;
37  AVCodecParameters *origin_par = NULL;
38  AVFrame *fr = NULL;
39  uint8_t *byte_buffer = NULL;
40  AVPacket *pkt;
42  int number_of_written_bytes;
43  int video_stream;
44  int byte_buffer_size;
45  int i = 0;
46  int result;
47 
49  if (result < 0) {
50  av_log(NULL, AV_LOG_ERROR, "Can't open file\n");
51  return result;
52  }
53 
55  if (result < 0) {
56  av_log(NULL, AV_LOG_ERROR, "Can't get stream info\n");
57  return result;
58  }
59 
61  if (video_stream < 0) {
62  av_log(NULL, AV_LOG_ERROR, "Can't find video stream in input file\n");
63  return -1;
64  }
65 
66  origin_par = fmt_ctx->streams[video_stream]->codecpar;
67 
68  codec = avcodec_find_decoder(origin_par->codec_id);
69  if (!codec) {
70  av_log(NULL, AV_LOG_ERROR, "Can't find decoder\n");
71  return -1;
72  }
73 
74  ctx = avcodec_alloc_context3(codec);
75  if (!ctx) {
76  av_log(NULL, AV_LOG_ERROR, "Can't allocate decoder context\n");
77  return AVERROR(ENOMEM);
78  }
79 
80  result = avcodec_parameters_to_context(ctx, origin_par);
81  if (result) {
82  av_log(NULL, AV_LOG_ERROR, "Can't copy decoder context\n");
83  return result;
84  }
85 
86  result = avcodec_open2(ctx, codec, NULL);
87  if (result < 0) {
88  av_log(ctx, AV_LOG_ERROR, "Can't open decoder\n");
89  return result;
90  }
91 
92  fr = av_frame_alloc();
93  if (!fr) {
94  av_log(NULL, AV_LOG_ERROR, "Can't allocate frame\n");
95  return AVERROR(ENOMEM);
96  }
97 
98  pkt = av_packet_alloc();
99  if (!pkt) {
100  av_log(NULL, AV_LOG_ERROR, "Cannot allocate packet\n");
101  return AVERROR(ENOMEM);
102  }
103 
104  byte_buffer_size = av_image_get_buffer_size(ctx->pix_fmt, ctx->width, ctx->height, 16);
105  byte_buffer = av_malloc(byte_buffer_size);
106  if (!byte_buffer) {
107  av_log(NULL, AV_LOG_ERROR, "Can't allocate buffer\n");
108  return AVERROR(ENOMEM);
109  }
110 
112  i = 0;
113 
114  result = 0;
115  while (result >= 0) {
116  result = av_read_frame(fmt_ctx, pkt);
117  if (result >= 0 && pkt->stream_index != video_stream) {
119  continue;
120  }
121 
122  if (result < 0)
123  result = avcodec_send_packet(ctx, NULL);
124  else {
125  if (pkt->pts == AV_NOPTS_VALUE)
126  pkt->pts = pkt->dts = i;
127  result = avcodec_send_packet(ctx, pkt);
128  }
130 
131  if (result < 0) {
132  av_log(NULL, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
133  return result;
134  }
135 
136  while (result >= 0) {
137  result = avcodec_receive_frame(ctx, fr);
138  if (result == AVERROR_EOF)
139  goto finish;
140  else if (result == AVERROR(EAGAIN)) {
141  result = 0;
142  break;
143  } else if (result < 0) {
144  av_log(NULL, AV_LOG_ERROR, "Error decoding frame\n");
145  return result;
146  }
147 
148  number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size,
149  (const uint8_t* const *)fr->data, (const int*) fr->linesize,
150  ctx->pix_fmt, ctx->width, ctx->height, 1);
151  if (number_of_written_bytes < 0) {
152  av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n");
153  av_frame_unref(fr);
154  return number_of_written_bytes;
155  }
156  printf("%d, %s, %s, %8"PRId64", %8d, 0x%08lx\n", video_stream,
157  av_ts2str(fr->pts), av_ts2str(fr->pkt_dts), fr->pkt_duration,
158  number_of_written_bytes, av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes));
159 
160  av_frame_unref(fr);
161  }
162  i++;
163  }
164 
165 finish:
167  av_frame_free(&fr);
170  av_freep(&byte_buffer);
171  return 0;
172 }
173 
174 int main(int argc, char **argv)
175 {
176  if (argc < 2)
177  {
178  av_log(NULL, AV_LOG_ERROR, "Incorrect input\n");
179  return 1;
180  }
181 
182  if (video_decode_example(argv[1]) != 0)
183  return 1;
184 
185  return 0;
186 }
Public header for Adler-32 hash function implementation.
int main(int argc, char **argv)
static int video_decode_example(const char *input_filename)
H264 codec test.
Definition: api-h264-test.c:33
uint8_t
Libavcodec external API header.
Main libavformat public API header.
#define NULL
Definition: coverity.c:32
static AVFormatContext * fmt_ctx
static AVStream * video_stream
static const char * input_filename
Definition: ffplay.c:312
int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
Definition: avcodec.c:144
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:946
int avcodec_parameters_to_context(AVCodecContext *codec, const AVCodecParameters *par)
Fill the codec context based on the values from the supplied codec parameters.
Definition: codec_par.c:147
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:173
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:188
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Return decoded output data from a decoder.
Definition: decode.c:652
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Supply raw packet data as input to a decoder.
Definition: decode.c:589
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:75
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:634
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:64
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
Definition: utils.c:1741
int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb, int related_stream, AVCodec **decoder_ret, int flags)
Find the "best" stream in the file.
Definition: utils.c:4230
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
Read packets of a media file to get stream information.
Definition: utils.c:3602
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
Definition: utils.c:4481
int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
Definition: utils.c:512
unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, unsigned int len)
Calculate the Adler32 checksum of a buffer.
Definition: adler32.c:45
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AVERROR(e)
Definition: error.h:43
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters.
Definition: imgutils.c:466
int av_image_copy_to_buffer(uint8_t *dst, int dst_size, const uint8_t *const src_data[4], const int src_linesize[4], enum AVPixelFormat pix_fmt, int width, int height, int align)
Copy image data from an image into a buffer.
Definition: imgutils.c:505
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
misc image utilities
int i
Definition: input.c:407
main external API structure.
Definition: avcodec.h:536
This struct describes the properties of an encoded stream.
Definition: codec_par.h:52
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
AVCodec.
Definition: codec.h:197
Format I/O context.
Definition: avformat.h:1232
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1300
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:411
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
int64_t pkt_duration
duration of the corresponding packet, expressed in AVStream->time_base units, 0 if unknown.
Definition: frame.h:597
int64_t pkt_dts
DTS copied from the AVPacket that triggered returning this frame.
Definition: frame.h:427
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
This structure stores compressed data.
Definition: packet.h:346
int stream_index
Definition: packet.h:371
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:362
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:368
int num
Numerator.
Definition: rational.h:59
int den
Denominator.
Definition: rational.h:60
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1038
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:902
#define av_freep(p)
#define av_malloc(s)
#define av_log(a,...)
AVPacket * pkt
Definition: movenc.c:59
AVFormatContext * ctx
Definition: movenc.c:48
static void finish(void)
Definition: movenc.c:342
timestamp utils, mostly useful for debugging/logging purposes
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:54