HACK! added a hack to support mpeg2 video format
[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
38 #include "demux.h"
39 #include "util.h"
41 static AVFormatContext *
42 open_file(const char *filename)
43 {
44         AVFormatContext *afc;
45         int err = av_open_input_file(&afc, filename, NULL, 0, NULL);
47         if (!err)
48                 err = av_find_stream_info(afc);
50         if (err < 0) {
51                 ERROR("%s: lavf error %d", filename, err);
52                 exit(1);
53         }
55         dump_format(afc, 0, filename, 0);
57         return afc;
58 }
60 static AVStream *
61 find_stream(AVFormatContext *afc)
62 {
63         AVStream *st = NULL;
64         unsigned int i;
66         for (i = 0; i < afc->nb_streams; i++) {
67                 if (afc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && !st)
68                         st = afc->streams[i];
69                 else
70                         afc->streams[i]->discard = AVDISCARD_ALL;
71         }
73         return st;
74 }
76 static struct demux * open_stream(const char * filename, int *width, int *height)
77 {
78         AVFormatContext *afc = open_file(filename);
79         AVStream *st = find_stream(afc);
80         AVCodecContext *cc = st->codec;
81         AVBitStreamFilterContext *bsf = NULL;
82         struct demux *demux;
84         if ((cc->codec_id != CODEC_ID_H264) &&  (cc->codec_id != CODEC_ID_MPEG2VIDEO)){
85                 ERROR("could not open '%s': unsupported codec %d", filename, cc->codec_id);
86                 return NULL;
87         }
89         if (cc->extradata && cc->extradata_size > 0 && cc->extradata[0] == 1) {
90                 MSG("initializing bitstream filter");
91                 bsf = av_bitstream_filter_init("h264_mp4toannexb");
92                 if (!bsf) {
93                         ERROR("could not open '%s': failed to initialize bitstream filter", filename);
94                         return NULL;
95                 }
96         }
98         *width = cc->width;
99         *height = cc->height;
101         demux = calloc(1, sizeof(*demux));
103         demux->afc = afc;
104         demux->cc  = cc;
105         demux->st  = st;
106         demux->bsf = bsf;
108         return demux;
111 struct demux * demux_init(const char * filename, int *width, int *height)
113         av_register_all();
114         avcodec_register_all();
115         return open_stream(filename, width, height);
118 int demux_read(struct demux *demux, char *input, int size)
120         AVPacket pk = {};
122         while (!av_read_frame(demux->afc, &pk)) {
123                 if (pk.stream_index == demux->st->index) {
124                         uint8_t *buf;
125                         int bufsize;
127                         if (demux->bsf) {
128                                 int ret;
129                                 ret = av_bitstream_filter_filter(demux->bsf, demux->cc,
130                                                 NULL, &buf, &bufsize, pk.data, pk.size, 0);
131                                 if (ret < 0) {
132                                         ERROR("bsf error: %d", ret);
133                                         return 0;
134                                 }
135                         } else {
136                                 buf     = pk.data;
137                                 bufsize = pk.size;
138                         }
140                         if (bufsize > size)
141                                 bufsize = size;
143                         memcpy(input, buf, bufsize);
145                         if (demux->bsf)
146                                 av_free(buf);
148                         av_free_packet(&pk);
150                         return bufsize;
151                 }
152                 av_free_packet(&pk);
153         }
155         return 0;
158 int demux_rewind(struct demux *demux)
160         return av_seek_frame(demux->afc, demux->st->index, 0, AVSEEK_FLAG_FRAME);
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);