e4fc150c41fa6067852d57ea51a8f23dff7639fe
[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 char mpeg4head[45] = {0,0,0,0};
42 int esds_length;
43 unsigned char *esds_data;
44 extern int first_in_buff;
45 int get_esds_offset(const char *filename);
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) &&  (cc->codec_id != CODEC_ID_MPEG2VIDEO) && ( cc->codec_id !=  CODEC_ID_MPEG4)){
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         if(get_esds_offset(filename))
124                return NULL;
125         return open_stream(filename, width, height);
128 int get_esds_offset(const char *filename) {
129        FILE *inputStream;
130        int i=0;
131        unsigned char *buffer = NULL;
132        unsigned long fileLen;
133        int esds_index=0;
134        inputStream = fopen(filename,"rb");
135        if (!inputStream) {
136                printf("Unable to open %s\n",filename);
137                return -1;
138        }
139        // Get the length
140        fseek(inputStream, 0, SEEK_END);
141        fileLen=ftell(inputStream);
142        fseek(inputStream, 0, SEEK_SET);
143        buffer=malloc(fileLen);
144        if (!buffer) {
145                printf("Memory error!\n");
146                fclose(inputStream);
147                return -1;
148        }
149        // File to buffer
150        fread(buffer, fileLen, 1, inputStream);
151        fclose(inputStream);
152        printf("Buffer starts: %p\n", &buffer[0]);
153        printf("Buffer ends: %p\n", &buffer[fileLen]);
154        //Determines offset of known_string
155        for(i=0; i<fileLen; i++) {
156                if((buffer[i] == 0x65) && (buffer[++i] == 0x73))
157                if((buffer[++i] == 0x64) && (buffer[i+1] == 0x73)) {
158                        printf("data in buffer = %x  %x  %x %d \n",buffer[i],buffer[i+1],buffer[i+2],buffer[i+27]);
159                        esds_index = i+27;
160                        break;
161                }
162        }
163        esds_length= buffer[esds_index];
164        esds_data=malloc(esds_length);
165        for(i=1; i<=esds_length; i++) {
166                //printf(" index= %x \n",buffer[esds_index+i]);
167                esds_data[i-1]=buffer[esds_index+i];
168                printf(" index= %x \n",esds_data[i-1]);
169        }
170        free(buffer);
171        return 0;
176 int demux_read(struct demux *demux, char *input, int size)
178         AVPacket pk = {};
180         while (!av_read_frame(demux->afc, &pk)) {
181                 if (pk.stream_index == demux->st->index) {
182                         uint8_t *buf;
183                         int bufsize;
185                         if (demux->bsf) {
186                                 int ret;
187                                 ret = av_bitstream_filter_filter(demux->bsf, demux->cc,
188                                                 NULL, &buf, &bufsize, pk.data, pk.size, 0);
189                                 if (ret < 0) {
190                                         ERROR("bsf error: %d", ret);
191                                         return 0;
192                                 }
193                         } else {
194                                 buf     = pk.data;
195                                 bufsize = pk.size;
196                         }
198                         if (bufsize > size)
199                                 bufsize = size;
201                         if(first_in_buff == 1) {
202                                memcpy(input,esds_data,esds_length);
203                                memcpy(input+esds_length, buf, bufsize);
204                                first_in_buff =0;
205                                bufsize = bufsize+esds_length;
206                         }
207                         else {
208                                memcpy(input, buf, bufsize);
209                         }
211                         if (demux->bsf)
212                                 av_free(buf);
214                         av_free_packet(&pk);
216                         return bufsize;
217                 }
218                 av_free_packet(&pk);
219         }
221         return 0;
224 int demux_rewind(struct demux *demux)
226         return av_seek_frame(demux->afc, demux->st->index, 0, AVSEEK_FLAG_FRAME);
229 void demux_deinit(struct demux *demux)
231         av_close_input_file(demux->afc);
232         if (demux->bsf)
233                 av_bitstream_filter_close(demux->bsf);
234         free(demux);