viddec: support for multiple decoder instances
[glsdk/omapdrmtest.git] / util / demux.c
1 /*
2  * Copyright (c) 2011, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
37 #include <libavformat/avformat.h>
38 #include <libavcodec/avcodec.h>
40 #include "util.h"
42 struct demux {
43         AVFormatContext *afc;
44         AVStream *st;
45         AVCodecContext *cc;
46         AVBitStreamFilterContext *bsf;
47 };
49 static AVFormatContext *
50 open_file(const char *filename)
51 {
52         AVFormatContext *afc;
53         int err = av_open_input_file(&afc, filename, NULL, 0, NULL);
55         if (!err)
56                 err = av_find_stream_info(afc);
58         if (err < 0) {
59                 ERROR("%s: lavf error %d", filename, err);
60                 exit(1);
61         }
63         dump_format(afc, 0, filename, 0);
65         return afc;
66 }
68 static AVStream *
69 find_stream(AVFormatContext *afc)
70 {
71         AVStream *st = NULL;
72         unsigned int i;
74         for (i = 0; i < afc->nb_streams; i++) {
75                 if (afc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && !st)
76                         st = afc->streams[i];
77                 else
78                         afc->streams[i]->discard = AVDISCARD_ALL;
79         }
81         return st;
82 }
84 static struct demux * open_stream(const char * filename, int *width, int *height)
85 {
86         AVFormatContext *afc = open_file(filename);
87         AVStream *st = find_stream(afc);
88         AVCodecContext *cc = st->codec;
89         AVBitStreamFilterContext *bsf = NULL;
90         struct demux *demux;
92         if (cc->codec_id != CODEC_ID_H264) {
93                 ERROR("could not open '%s': unsupported codec %d", filename, cc->codec_id);
94                 return NULL;
95         }
97         if (cc->extradata && cc->extradata_size > 0 && cc->extradata[0] == 1) {
98                 MSG("initializing bitstream filter");
99                 bsf = av_bitstream_filter_init("h264_mp4toannexb");
100                 if (!bsf) {
101                         ERROR("could not open '%s': failed to initialize bitstream filter", filename);
102                         return NULL;
103                 }
104         }
106         *width = cc->width;
107         *height = cc->height;
109         demux = calloc(1, sizeof(*demux));
111         demux->afc = afc;
112         demux->cc  = cc;
113         demux->st  = st;
114         demux->bsf = bsf;
116         return demux;
119 struct demux * demux_init(const char * filename, int *width, int *height)
121         av_register_all();
122         avcodec_register_all();
123         return open_stream(filename, width, height);
126 int demux_read(struct demux *demux, char *input, int size)
128         AVPacket pk = {};
130         while (!av_read_frame(demux->afc, &pk)) {
131                 if (pk.stream_index == demux->st->index) {
132                         uint8_t *buf;
133                         int bufsize;
135                         if (demux->bsf) {
136                                 int ret;
137                                 ret = av_bitstream_filter_filter(demux->bsf, demux->cc,
138                                                 NULL, &buf, &bufsize, pk.data, pk.size, 0);
139                                 if (ret < 0) {
140                                         ERROR("bsf error: %d", ret);
141                                         return 0;
142                                 }
143                         } else {
144                                 buf     = pk.data;
145                                 bufsize = pk.size;
146                         }
148                         if (bufsize > size)
149                                 bufsize = size;
151                         memcpy(input, buf, bufsize);
153                         if (demux->bsf)
154                                 av_free(buf);
156                         av_free_packet(&pk);
158                         return bufsize;
159                 }
160                 av_free_packet(&pk);
161         }
163         return 0;
166 void demux_deinit(struct demux *demux)
168         av_close_input_file(demux->afc);
169         if (demux->bsf)
170                 av_bitstream_filter_close(demux->bsf);
171         free(demux);