Merge remote branch 'origin/master' into pipe-video
[mesa.git] / src / gallium / state_trackers / vdpau / mpeg2_bitstream_parser.c
1 /**************************************************************************
2 *
3 * Copyright 2010 Thomas Balling Sørensen.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include "mpeg2_bitstream_parser.h"
30
31 int
32 vlVdpMPEG2NextStartCode(struct vdpMPEG2BitstreamParser *parser)
33 {
34 uint32_t integer = 0xffffff00;
35 uint8_t * ptr_read = parser->ptr_bitstream;
36 int8_t * bytes_to_end;
37
38 bytes_to_end = parser->ptr_bitstream_end - parser->ptr_bitstream;
39
40 /* Read byte after byte, until startcode is found */
41 while(integer != 0x00000100)
42 {
43 if (bytes_to_end <= 0)
44 {
45 parser->state = MPEG2_BITSTREAM_DONE;
46 parser->code = 0;
47 return 0;
48 }
49 integer = ( integer | *ptr_read++ ) << 8;
50 bytes_to_end--;
51 }
52 parser->ptr_bitstream = ptr_read;
53 parser->code = parser->ptr_bitstream;
54 /* start_code found. rewind cursor a byte */
55 //parser->cursor -= 8;
56
57 return 0;
58 }
59
60 int
61 vlVdpMPEG2BitstreamToMacroblock (
62 struct pipe_screen *screen,
63 VdpBitstreamBuffer const *bitstream_buffers,
64 uint32_t bitstream_buffer_count,
65 unsigned int *num_macroblocks,
66 struct pipe_mpeg12_macroblock **pipe_macroblocks)
67 {
68 bool b_header_done = false;
69 struct vdpMPEG2BitstreamParser parser;
70
71 #if(1)
72 FILE *fp;
73
74 if ((fp = fopen("binout", "w"))==NULL) {
75 printf("Cannot open file.\n");
76 exit(1);
77 }
78 fwrite(bitstream_buffers[0].bitstream, 1, bitstream_buffers[0].bitstream_bytes, fp);
79 fclose(fp);
80
81 #endif
82
83
84 debug_printf("[VDPAU] Starting decoding MPEG2 stream\n");
85
86 num_macroblocks[0] = 0;
87
88 memset(&parser,0,sizeof(parser));
89 parser.state = MPEG2_HEADER_START_CODE;
90 parser.ptr_bitstream = (unsigned char *)bitstream_buffers[0].bitstream;
91 parser.ptr_bitstream_end = parser.ptr_bitstream + bitstream_buffers[0].bitstream_bytes;
92
93 /* Main header parser loop */
94 while(!b_header_done)
95 {
96 switch (parser.state)
97 {
98 case MPEG2_SEEK_HEADER:
99 if (vlVdpMPEG2NextStartCode(&parser))
100 exit(1);
101 break;
102 /* Start_code found */
103 switch (parser.code)
104 {
105 /* sequence_header_code */
106 case 0xB3:
107 debug_printf("[VDPAU][Bitstream parser] Sequence header code found\n");
108
109 /* We dont need to read this, because we already have this information */
110 break;
111 case 0xB5:
112 debug_printf("[VDPAU][Bitstream parser] Extension start code found\n");
113 //exit(1);
114 break;
115
116 case 0xB8:
117 debug_printf("[VDPAU][Bitstream parser] Extension start code found\n");
118 //exit(1);
119 break;
120
121 }
122
123 break;
124 case MPEG2_BITSTREAM_DONE:
125 if (parser.cur_bitstream < bitstream_buffer_count - 1)
126 {
127 debug_printf("[VDPAU][Bitstream parser] Done parsing current bitstream. Moving to the next\n");
128 parser.cur_bitstream++;
129 parser.ptr_bitstream = (unsigned char *)bitstream_buffers[parser.cur_bitstream].bitstream;
130 parser.ptr_bitstream_end = parser.ptr_bitstream + bitstream_buffers[parser.cur_bitstream].bitstream_bytes;
131 parser.state = MPEG2_HEADER_START_CODE;
132 }
133 else
134 {
135 debug_printf("[VDPAU][Bitstream parser] Done with frame\n");
136 exit(0);
137 // return 0;
138 }
139 break;
140
141 }
142
143
144 }
145
146
147 return 0;
148 }
149