vo_mga: switch to newer screen dimension handling API
[mplayer.git] / libmpdemux / parse_es.c
blob05507a495a8d522dfbe165dfcf5a79b64b5cbd6c
1 /*
2 * MPEG-ES video parser
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
26 #include "config.h"
27 #include "mp_msg.h"
29 #include "stream/stream.h"
30 #include "demuxer.h"
31 #include "parse_es.h"
33 //static unsigned char videobuffer[MAX_VIDEO_PACKET_SIZE];
34 unsigned char* videobuffer=NULL;
35 int videobuf_len=0;
36 int next_nal = -1;
37 ///! legacy variable, 4 if stream is synced, 0 if not
38 int videobuf_code_len=0;
40 #define MAX_SYNCLEN (10 * 1024 * 1024)
41 // sync video stream, and returns next packet code
42 int sync_video_packet(demux_stream_t *ds){
43 if (!videobuf_code_len) {
44 int skipped=0;
45 if (!demux_pattern_3(ds, NULL, MAX_SYNCLEN, &skipped, 0x100)) {
46 if (skipped == MAX_SYNCLEN)
47 mp_msg(MSGT_DEMUXER, MSGL_ERR, "parse_es: could not sync video stream!\n");
48 goto eof_out;
50 next_nal = demux_getc(ds);
51 if (next_nal < 0)
52 goto eof_out;
53 videobuf_code_len = 4;
54 if(skipped) mp_dbg(MSGT_PARSEES,MSGL_DBG2,"videobuf: %d bytes skipped (next: 0x1%02X)\n",skipped,next_nal);
56 return 0x100|next_nal;
58 eof_out:
59 next_nal = -1;
60 videobuf_code_len = 0;
61 return 0;
64 // return: packet length
65 int read_video_packet(demux_stream_t *ds){
66 int packet_start;
67 int res, read;
69 if (VIDEOBUFFER_SIZE - videobuf_len < 5)
70 return 0;
71 // SYNC STREAM
72 // if(!sync_video_packet(ds)) return 0; // cannot sync (EOF)
74 // COPY STARTCODE:
75 packet_start=videobuf_len;
76 videobuffer[videobuf_len+0]=0;
77 videobuffer[videobuf_len+1]=0;
78 videobuffer[videobuf_len+2]=1;
79 videobuffer[videobuf_len+3]=next_nal;
80 videobuf_len+=4;
82 // READ PACKET:
83 res = demux_pattern_3(ds, &videobuffer[videobuf_len],
84 VIDEOBUFFER_SIZE - videobuf_len, &read, 0x100);
85 videobuf_len += read;
86 if (!res)
87 goto eof_out;
89 videobuf_len-=3;
91 mp_dbg(MSGT_PARSEES,MSGL_DBG2,"videobuf: packet 0x1%02X len=%d (total=%d)\n",videobuffer[packet_start+3],videobuf_len-packet_start,videobuf_len);
93 // Save next packet code:
94 next_nal = demux_getc(ds);
95 if (next_nal < 0)
96 goto eof_out;
97 videobuf_code_len=4;
99 return videobuf_len-packet_start;
101 eof_out:
102 next_nal = -1;
103 videobuf_code_len = 0;
104 return videobuf_len - packet_start;
107 // return: next packet code
108 int skip_video_packet(demux_stream_t *ds){
110 // SYNC STREAM
111 // if(!sync_video_packet(ds)) return 0; // cannot sync (EOF)
113 videobuf_code_len=0; // force resync
115 // SYNC AGAIN:
116 return sync_video_packet(ds);
119 /* stripped down version of a52_syncinfo() from liba52
120 * copyright belongs to Michel Lespinasse <walken@zoy.org>
121 * and Aaron Holtzman <aholtzma@ess.engr.uvic.ca> */
122 int mp_a52_framesize(uint8_t * buf, int *srate)
124 int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
125 128, 160, 192, 224, 256, 320, 384, 448,
126 512, 576, 640
128 uint8_t halfrate[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
129 int frmsizecod, bitrate, half;
131 if ((buf[0] != 0x0b) || (buf[1] != 0x77)) /* syncword */
132 return 0;
134 if (buf[5] >= 0x60) /* bsid >= 12 */
135 return 0;
137 half = halfrate[buf[5] >> 3];
139 frmsizecod = buf[4] & 63;
140 if (frmsizecod >= 38)
141 return 0;
143 bitrate = rate[frmsizecod >> 1];
145 switch (buf[4] & 0xc0) {
146 case 0: /* 48 KHz */
147 *srate = 48000 >> half;
148 return 4 * bitrate;
149 case 0x40: /* 44.1 KHz */
150 *srate = 44100 >> half;
151 return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
152 case 0x80: /* 32 KHz */
153 *srate = 32000 >> half;
154 return 6 * bitrate;
157 return 0;