add viddec3 decoder test
[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 #include <libavformat/avformat.h>
34 #include <libavcodec/avcodec.h>
36 #include "util.h"
38 struct demux {
39         AVFormatContext *afc;
40         AVStream *st;
41         AVCodecContext *cc;
42         AVBitStreamFilterContext *bsf;
43 };
45 static AVFormatContext *
46 open_file(const char *filename)
47 {
48         AVFormatContext *afc;
49         int err = av_open_input_file(&afc, filename, NULL, 0, NULL);
51         if (!err)
52                 err = av_find_stream_info(afc);
54         if (err < 0) {
55                 ERROR("%s: lavf error %d", filename, err);
56                 exit(1);
57         }
59         dump_format(afc, 0, filename, 0);
61         return afc;
62 }
64 static AVStream *
65 find_stream(AVFormatContext *afc)
66 {
67         AVStream *st = NULL;
68         unsigned int i;
70         for (i = 0; i < afc->nb_streams; i++) {
71                 if (afc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && !st)
72                         st = afc->streams[i];
73                 else
74                         afc->streams[i]->discard = AVDISCARD_ALL;
75         }
77         return st;
78 }
80 static struct demux * open_stream(const char * filename, int *width, int *height)
81 {
82         AVFormatContext *afc = open_file(filename);
83         AVStream *st = find_stream(afc);
84         AVCodecContext *cc = st->codec;
85         AVBitStreamFilterContext *bsf = NULL;
86         struct demux *demux;
88         if (cc->codec_id != CODEC_ID_H264) {
89                 ERROR("could not open '%s': unsupported codec %d", filename, cc->codec_id);
90                 return NULL;
91         }
93         if (cc->extradata && cc->extradata_size > 0 && cc->extradata[0] == 1) {
94                 MSG("initializing bitstream filter");
95                 bsf = av_bitstream_filter_init("h264_mp4toannexb");
96                 if (!bsf) {
97                         ERROR("could not open '%s': failed to initialize bitstream filter", filename);
98                         return NULL;
99                 }
100         }
102         *width = cc->width;
103         *height = cc->height;
105         demux = calloc(1, sizeof(*demux));
107         demux->afc = afc;
108         demux->cc  = cc;
109         demux->st  = st;
110         demux->bsf = bsf;
112         return demux;
115 struct demux * demux_init(const char * filename, int *width, int *height)
117         av_register_all();
118         avcodec_register_all();
119         return open_stream(filename, width, height);
122 int demux_read(struct demux *demux, char *input, int size)
124         AVPacket pk = {};
126         while (!av_read_frame(demux->afc, &pk)) {
127                 if (pk.stream_index == demux->st->index) {
128                         uint8_t *buf;
129                         int bufsize;
131                         if (demux->bsf) {
132                                 int ret;
133                                 MSG("%p %d bytes", pk.data, pk.size);
134                                 ret = av_bitstream_filter_filter(demux->bsf, demux->cc,
135                                                 NULL, &buf, &bufsize, pk.data, pk.size, 0);
136                                 if (ret < 0) {
137                                         ERROR("bsf error: %d", ret);
138                                         return 0;
139                                 }
140                         } else {
141                                 buf     = pk.data;
142                                 bufsize = pk.size;
143                         }
145                         if (bufsize > size)
146                                 bufsize = size;
148                         memcpy(input, buf, bufsize);
150                         if (demux->bsf)
151                                 av_free(buf);
153                         av_free_packet(&pk);
155                         return bufsize;
156                 }
157                 av_free_packet(&pk);
158         }
160         return 0;
163 void demux_deinit(struct demux *demux)
165         av_close_input_file(demux->afc);
166         if (demux->bsf)
167                 av_bitstream_filter_close(demux->bsf);
168         free(demux);