FFmpeg
Loading...
Searching...
No Matches
uncoded_frame.c
Go to the documentation of this file.
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
5#include "libavutil/mem.h"
10#include "libavcodec/codec_id.h"
11
12typedef struct {
16} Stream;
17
18static int create_sink(Stream *st, AVFilterGraph *graph,
19 AVFilterContext *f, int idx)
20{
21 enum AVMediaType type = avfilter_pad_get_type(f->output_pads, idx);
22 const char *sink_name;
23 int ret;
24
25 switch (type) {
26 case AVMEDIA_TYPE_VIDEO: sink_name = "buffersink"; break;
27 case AVMEDIA_TYPE_AUDIO: sink_name = "abuffersink"; break;
28 default:
29 av_log(NULL, AV_LOG_ERROR, "Stream type not supported\n");
30 return AVERROR(EINVAL);
31 }
33 avfilter_get_by_name(sink_name),
34 NULL, NULL, NULL, graph);
35 if (ret < 0)
36 return ret;
37 ret = avfilter_link(f, idx, st->sink, 0);
38 if (ret < 0)
39 return ret;
40 return 0;
41}
42
43int main(int argc, char **argv)
44{
45 char *in_graph_desc, **out_dev_name;
46 int nb_out_dev = 0, nb_streams = 0;
47 AVFilterGraph *in_graph = NULL;
48 Stream *streams = NULL, *st;
50 int i, j, run = 1, ret;
51
52 //av_log_set_level(AV_LOG_DEBUG);
53
54 if (argc < 3) {
56 "Usage: %s filter_graph dev:out [dev2:out2...]\n\n"
57 "Examples:\n"
58 "%s movie=file.nut:s=v+a xv:- alsa:default\n"
59 "%s movie=file.nut:s=v+a uncodedframecrc:pipe:0\n",
60 argv[0], argv[0], argv[0]);
61 exit(1);
62 }
63 in_graph_desc = argv[1];
64 out_dev_name = argv + 2;
65 nb_out_dev = argc - 2;
66
68
69 /* Create input graph */
70 if (!(in_graph = avfilter_graph_alloc())) {
71 ret = AVERROR(ENOMEM);
72 av_log(NULL, AV_LOG_ERROR, "Unable to alloc graph graph: %s\n",
73 av_err2str(ret));
74 goto fail;
75 }
76 ret = avfilter_graph_parse_ptr(in_graph, in_graph_desc, NULL, NULL, NULL);
77 if (ret < 0) {
78 av_log(NULL, AV_LOG_ERROR, "Unable to parse graph: %s\n",
79 av_err2str(ret));
80 goto fail;
81 }
82 nb_streams = 0;
83 for (i = 0; i < in_graph->nb_filters; i++) {
84 AVFilterContext *f = in_graph->filters[i];
85 for (j = 0; j < f->nb_inputs; j++) {
86 if (!f->inputs[j]) {
87 av_log(NULL, AV_LOG_ERROR, "Graph has unconnected inputs\n");
88 ret = AVERROR(EINVAL);
89 goto fail;
90 }
91 }
92 for (j = 0; j < f->nb_outputs; j++)
93 if (!f->outputs[j])
94 nb_streams++;
95 }
96 if (!nb_streams) {
97 av_log(NULL, AV_LOG_ERROR, "Graph has no output stream\n");
98 ret = AVERROR(EINVAL);
99 goto fail;
100 }
101 if (nb_out_dev != 1 && nb_out_dev != nb_streams) {
103 "Graph has %d output streams, %d devices given\n",
104 nb_streams, nb_out_dev);
105 ret = AVERROR(EINVAL);
106 goto fail;
107 }
108
109 if (!(streams = av_calloc(nb_streams, sizeof(*streams)))) {
110 ret = AVERROR(ENOMEM);
111 av_log(NULL, AV_LOG_ERROR, "Could not allocate streams\n");
112 }
113 st = streams;
114 for (i = 0; i < in_graph->nb_filters; i++) {
115 AVFilterContext *f = in_graph->filters[i];
116 for (j = 0; j < f->nb_outputs; j++) {
117 if (!f->outputs[j]) {
118 if ((ret = create_sink(st++, in_graph, f, j)) < 0)
119 goto fail;
120 }
121 }
122 }
123 av_assert0(st - streams == nb_streams);
124 if ((ret = avfilter_graph_config(in_graph, NULL)) < 0) {
125 av_log(NULL, AV_LOG_ERROR, "Failed to configure graph\n");
126 goto fail;
127 }
128
129 /* Create output devices */
130 for (i = 0; i < nb_out_dev; i++) {
131 char *fmt = NULL, *dev = out_dev_name[i];
132 st = &streams[i];
133 if ((dev = strchr(dev, ':'))) {
134 *(dev++) = 0;
135 fmt = out_dev_name[i];
136 }
137 ret = avformat_alloc_output_context2(&st->mux, NULL, fmt, dev);
138 if (ret < 0) {
139 av_log(NULL, AV_LOG_ERROR, "Failed to allocate output: %s\n",
140 av_err2str(ret));
141 goto fail;
142 }
143 if (!(st->mux->oformat->flags & AVFMT_NOFILE)) {
144 ret = avio_open2(&st->mux->pb, st->mux->url, AVIO_FLAG_WRITE,
145 NULL, NULL);
146 if (ret < 0) {
147 av_log(st->mux, AV_LOG_ERROR, "Failed to init output: %s\n",
148 av_err2str(ret));
149 goto fail;
150 }
151 }
152 }
153 for (; i < nb_streams; i++)
154 streams[i].mux = streams[0].mux;
155
156 /* Create output device streams */
157 for (i = 0; i < nb_streams; i++) {
158 st = &streams[i];
159 if (!(st->stream = avformat_new_stream(st->mux, NULL))) {
160 ret = AVERROR(ENOMEM);
161 av_log(NULL, AV_LOG_ERROR, "Failed to create output stream\n");
162 goto fail;
163 }
165 st->stream->time_base = av_buffersink_get_time_base(st->sink);
166 switch (av_buffersink_get_type(st->sink)) {
168 st->stream->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO;
169 st->stream->avg_frame_rate =
170 st->stream-> r_frame_rate = av_buffersink_get_frame_rate(st->sink);
171 st->stream->codecpar->width = av_buffersink_get_w(st->sink);
172 st->stream->codecpar->height = av_buffersink_get_h(st->sink);
173 st->stream->codecpar->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(st->sink);
174 st->stream->codecpar->format = av_buffersink_get_format(st->sink);
175 break;
177 ret = av_buffersink_get_ch_layout(st->sink, &st->stream->codecpar->ch_layout);
178 if (ret < 0)
179 goto fail;
180 st->stream->codecpar->sample_rate = av_buffersink_get_sample_rate(st->sink);
181 st->stream->codecpar->format = av_buffersink_get_format(st->sink);
182 st->stream->codecpar->codec_id = av_get_pcm_codec(st->stream->codecpar->format, -1);
183 break;
184 default:
185 av_assert0(!"reached");
186 }
187 }
188
189 /* Init output devices */
190 for (i = 0; i < nb_out_dev; i++) {
191 st = &streams[i];
192 if ((ret = avformat_write_header(st->mux, NULL)) < 0) {
193 av_log(st->mux, AV_LOG_ERROR, "Failed to init output: %s\n",
194 av_err2str(ret));
195 goto fail;
196 }
197 }
198
199 /* Check output devices */
200 for (i = 0; i < nb_streams; i++) {
201 st = &streams[i];
202 ret = av_write_uncoded_frame_query(st->mux, st->stream->index);
203 if (ret < 0) {
204 av_log(st->mux, AV_LOG_ERROR,
205 "Uncoded frames not supported on stream #%d: %s\n",
206 i, av_err2str(ret));
207 goto fail;
208 }
209 }
210
211 while (run) {
212 ret = avfilter_graph_request_oldest(in_graph);
213 if (ret < 0) {
214 if (ret == AVERROR_EOF) {
215 run = 0;
216 } else {
217 av_log(NULL, AV_LOG_ERROR, "Error filtering: %s\n",
218 av_err2str(ret));
219 break;
220 }
221 }
222 for (i = 0; i < nb_streams; i++) {
223 st = &streams[i];
224 while (1) {
225 if (!frame && !(frame = av_frame_alloc())) {
226 ret = AVERROR(ENOMEM);
227 av_log(NULL, AV_LOG_ERROR, "Could not allocate frame\n");
228 goto fail;
229 }
230 ret = av_buffersink_get_frame_flags(st->sink, frame,
232 if (ret < 0) {
233 if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
234 av_log(NULL, AV_LOG_WARNING, "Error in sink: %s\n",
235 av_err2str(ret));
236 break;
237 }
238 if (frame->pts != AV_NOPTS_VALUE)
239 frame->pts = av_rescale_q(frame->pts,
241 st->stream->time_base);
243 st->stream->index,
244 frame);
245 frame = NULL;
246 if (ret < 0) {
247 av_log(st->mux, AV_LOG_ERROR,
248 "Error writing frame: %s\n", av_err2str(ret));
249 goto fail;
250 }
251 }
252 }
253 }
254 ret = 0;
255
256 for (i = 0; i < nb_out_dev; i++) {
257 st = &streams[i];
258 av_write_trailer(st->mux);
259 }
260
261fail:
263 avfilter_graph_free(&in_graph);
264 if (streams) {
265 for (i = 0; i < nb_out_dev; i++) {
266 st = &streams[i];
267 if (st->mux) {
268 if (st->mux->pb)
269 avio_closep(&st->mux->pb);
270 avformat_free_context(st->mux);
271 }
272 }
273 }
274 av_freep(&streams);
275 return ret < 0;
276}
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Main libavdevice API header.
Main libavfilter public API header.
Main libavformat public API header.
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition avformat.h:488
int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition mux.c:95
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
Definition avio.c:717
int avio_open2(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition avio.c:559
#define AVIO_FLAG_WRITE
write-only
Definition avio.h:618
memory buffer sink API for audio and video
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define NULL
Definition coverity.c:32
static AVFrame * frame
int main
Definition dovi_rpuenc.c:38
static unsigned int nb_streams
Definition ffprobe.c:352
#define fail
Definition test.h:479
enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be)
Return the PCM codec associated with a sample format.
Definition utils.c:534
@ AV_CODEC_ID_RAWVIDEO
Definition codec_id.h:63
FF_VISIBILITY_POP_HIDDEN av_cold void avdevice_register_all(void)
Initialize libavdevice and register all the input and output devices.
Definition alldevices.c:67
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition avformat.c:150
av_warn_unused_result int avformat_write_header(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and write the stream header to an output media file.
Definition mux.c:467
int av_interleaved_write_uncoded_frame(AVFormatContext *s, int stream_index, struct AVFrame *frame)
Write an uncoded frame to an output media file.
Definition mux.c:1422
int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index)
Test whether a muxer supports uncoded frame.
Definition mux.c:1428
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition mux.c:1238
enum AVMediaType av_buffersink_get_type(const AVFilterContext *ctx)
int av_buffersink_get_sample_rate(const AVFilterContext *ctx)
int av_buffersink_get_format(const AVFilterContext *ctx)
AVRational av_buffersink_get_frame_rate(const AVFilterContext *ctx)
Definition buffersink.c:254
int av_buffersink_get_h(const AVFilterContext *ctx)
AVRational av_buffersink_get_sample_aspect_ratio(const AVFilterContext *ctx)
int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out)
Definition buffersink.c:274
AVRational av_buffersink_get_time_base(const AVFilterContext *ctx)
int av_buffersink_get_w(const AVFilterContext *ctx)
int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
Get a frame with filtered data from sink and put it in frame.
Definition buffersink.c:135
#define AV_BUFFERSINK_FLAG_NO_REQUEST
Tell av_buffersink_get_buffer_ref() not to request a frame from its input.
Definition buffersink.h:92
int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
Check validity and configure all the links and formats in the graph.
const AVFilter * avfilter_get_by_name(const char *name)
Get a filter definition matching the given name.
Definition allfilters.c:654
enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
Get the type of an AVFilterPad.
Definition avfilter.c:993
int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs, void *log_ctx)
Add a graph described by a string to a graph.
void avfilter_graph_free(AVFilterGraph **graph)
Free a graph, destroy its links, and set *graph to NULL.
int avfilter_graph_request_oldest(AVFilterGraph *graph)
Request a frame on the oldest sink link.
int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad)
Link two filters together.
Definition avfilter.c:149
int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt, const char *name, const char *args, void *opaque, AVFilterGraph *graph_ctx)
A convenience wrapper that allocates and initializes a filter in a single step.
AVFilterGraph * avfilter_graph_alloc(void)
Allocate a filter graph.
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
AVMediaType
Definition avutil.h:198
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
cl_device_type type
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
An instance of a filter.
Definition avfilter.h:273
unsigned nb_filters
Definition avfilter.h:564
AVFilterContext ** filters
Definition avfilter.h:563
Format I/O context.
Definition avformat.h:1333
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
AVFilterContext * sink
AVStream * stream
AVFormatContext * mux
uint8_t run
Definition svq3.c:207
#define av_freep(p)
#define av_log(a,...)
static int create_sink(Stream *st, AVFilterGraph *graph, AVFilterContext *f, int idx)