2 * The real io-stuff is in tarkin-io.c
3 * (this one has to be rewritten to write ogg streams ...)
15 TarkinStream
* tarkin_stream_new ()
17 TarkinStream
*s
= (TarkinStream
*) CALLOC (1, sizeof(TarkinStream
));
21 memset(s
,0,sizeof(*s
));
23 s
->frames_per_buf
= N_FRAMES
;
29 void tarkin_stream_destroy (TarkinStream
*s
)
36 for (i
=0; i
<s
->n_layers
; i
++) {
37 if (s
->layer
[i
].waveletbuf
) {
38 for (j
=0; j
<s
->layer
[i
].n_comp
; j
++) {
39 wavelet_3d_buf_destroy (s
->layer
[i
].waveletbuf
[j
]);
40 FREE (s
->layer
[i
].packet
[j
].data
);
42 FREE(s
->layer
[i
].waveletbuf
);
43 FREE(s
->layer
[i
].packet
);
50 if (s
->headers
.header
)
51 FREE(s
->headers
.header
);
53 if (s
->headers
.header1
)
54 FREE(s
->headers
.header1
);
56 if (s
->headers
.header2
)
57 FREE(s
->headers
.header2
);
64 int tarkin_analysis_init(TarkinStream
*s
, TarkinInfo
*ti
,
65 TarkinError (*free_frame
)(void *s
, void *ptr
),
66 TarkinError (*packet_out
)(void *s
, ogg_packet
*ptr
),
69 if((!ti
->inter
.numerator
)||(!ti
->inter
.denominator
))return (-TARKIN_FAULT
);
70 if((!free_frame
) || (!packet_out
)) return (-TARKIN_FAULT
);
72 s
->free_frame
= free_frame
;
73 s
->packet_out
= packet_out
;
74 s
->user_ptr
= user_ptr
;
79 extern int tarkin_analysis_add_layer(TarkinStream
*s
,
80 TarkinVideoLayerDesc
*tvld
)
83 TarkinVideoLayer
*layer
;
85 s
->layer
= REALLOC(s
->layer
,(s
->n_layers
+1) * sizeof(*s
->layer
));
87 s
->layer
= MALLOC(sizeof(*s
->layer
));
89 layer
= s
->layer
+ s
->n_layers
;
90 memset(layer
,0,sizeof(*s
->layer
));
91 memcpy (&layer
->desc
, tvld
, sizeof(TarkinVideoLayerDesc
));
94 s
->ti
->n_layers
= s
->n_layers
;
95 s
->ti
->layer
= s
->layer
;
97 switch (layer
->desc
.format
) {
98 case TARKIN_GRAYSCALE
:
100 layer
->color_fwd_xform
= grayscale_to_y
;
101 layer
->color_inv_xform
= y_to_grayscale
;
105 layer
->color_fwd_xform
= rgb24_to_yuv
;
106 layer
->color_inv_xform
= yuv_to_rgb24
;
110 layer
->color_fwd_xform
= rgb32_to_yuv
;
111 layer
->color_inv_xform
= yuv_to_rgb32
;
115 layer
->color_fwd_xform
= rgba_to_yuv
;
116 layer
->color_inv_xform
= yuv_to_rgba
;
119 return -TARKIN_INVALID_COLOR_FORMAT
;
123 printf("dbg_ogg:add_layer %d with %d components\n",
124 s
->n_layers
, layer
->n_comp
);
127 layer
->waveletbuf
= (Wavelet3DBuf
**) CALLOC (layer
->n_comp
,
128 sizeof(Wavelet3DBuf
*));
130 layer
->packet
= MALLOC (layer
->n_comp
* sizeof(*layer
->packet
));
131 memset(layer
->packet
, 0, layer
->n_comp
* sizeof(*layer
->packet
));
133 for (i
=0; i
<layer
->n_comp
; i
++){
134 layer
->waveletbuf
[i
] = wavelet_3d_buf_new (layer
->desc
.width
,
136 layer
->desc
.frames_per_buf
);
137 layer
->packet
[i
].data
= MALLOC(layer
->desc
.bitstream_len
);
138 layer
->packet
[i
].storage
= layer
->desc
.bitstream_len
;
141 max_bitstream_len += layer->desc.bitstream_len
142 + 2 * 10 * sizeof(uint32_t) * layer->n_comp; // truncation tables
147 TarkinError
_analysis_packetout(TarkinStream
*s
, uint32_t layer_id
,
155 data
= s
->layer
[layer_id
].packet
[comp
].data
;
156 data_len
= s
->layer
[layer_id
].packet
[comp
].data_len
;
158 oggpack_writeinit(&opb
);
159 oggpack_write(&opb
,0,8); /* No feature flags for now */
160 oggpack_write(&opb
,layer_id
,12);
161 oggpack_write(&opb
,comp
,12);
162 for(i
=0;i
<data_len
;i
++)
163 oggpack_write(&opb
,*(data
+ i
), 8);
166 op
.e_o_s
= data_len
?0:1;
168 op
.bytes
= oggpack_bytes(&opb
)+4;
169 op
.packet
= opb
.buffer
;
171 printf("dbg_ogg: writing packet layer %d, comp %d, data_len %d %s\n",
172 layer_id
, comp
, data_len
, op
.e_o_s
?"eos":"");
174 s
->layer
[layer_id
].packet
[comp
].data_len
= 0; /* so direct call => eos */
175 return(s
->packet_out(s
,&op
));
178 void _stream_flush (TarkinStream
*s
)
182 s
->current_frame_in_buf
=0;
184 for (i
=0; i
<s
->n_layers
; i
++) {
185 TarkinVideoLayer
*layer
= &s
->layer
[i
];
187 for (j
=0; j
<layer
->n_comp
; j
++) {
188 uint32_t comp_bitstream_len
;
189 TarkinPacket
*packet
= layer
->packet
+ j
;
192 * implicit 6:1:1 subsampling
195 comp_bitstream_len
= 6*layer
->desc
.bitstream_len
/(layer
->n_comp
+5);
197 comp_bitstream_len
= layer
->desc
.bitstream_len
/(layer
->n_comp
+5);
199 if(packet
->storage
< comp_bitstream_len
) {
200 packet
->storage
= comp_bitstream_len
;
201 packet
->data
= REALLOC (packet
->data
, comp_bitstream_len
);
204 wavelet_3d_buf_dump ("color-%d-%03d.pgm",
206 layer
->waveletbuf
[j
], j
== 0 ? 0 : 128);
208 wavelet_3d_buf_fwd_xform (layer
->waveletbuf
[j
],
209 layer
->desc
.a_moments
,
210 layer
->desc
.s_moments
);
212 wavelet_3d_buf_dump ("coeff-%d-%03d.pgm",
214 layer
->waveletbuf
[j
], 128);
216 packet
->data_len
= wavelet_3d_buf_encode_coeff (layer
->waveletbuf
[j
],
220 _analysis_packetout (s
, i
, j
);
226 uint32_t tarkin_analysis_framein (TarkinStream
*s
, uint8_t *frame
,
227 uint32_t layer_id
, TarkinTime
*date
)
229 TarkinVideoLayer
*layer
;
230 if(!frame
) return (_analysis_packetout(s
, 0, 0)); /* eos */
231 if((layer_id
>=s
->n_layers
) || (date
->denominator
==0)) return (TARKIN_FAULT
);
233 layer
= s
->layer
+ layer_id
;
234 layer
->color_fwd_xform (frame
, layer
->waveletbuf
,
235 s
->current_frame_in_buf
);
236 /* We don't use this feature for now, neither date... */
237 s
->free_frame(s
,frame
);
239 s
->current_frame_in_buf
++;
241 if (s
->current_frame_in_buf
== s
->frames_per_buf
)
245 printf("dbg_ogg: framein at pos %d/%d, n° %d,%d on layer %d\n",
246 date
->numerator
, date
->denominator
,
247 layer
->frameno
, s
->current_frame
, layer_id
);
251 return (++s
->current_frame
);
258 * tarkin_stream_read_header() is now info.c:_tarkin_unpack_layer_desc()
263 TarkinError
tarkin_stream_get_layer_desc (TarkinStream
*s
,
265 TarkinVideoLayerDesc
*desc
)
267 if (layer_id
> s
->n_layers
-1)
268 return -TARKIN_INVALID_LAYER
;
270 memcpy (desc
, &(s
->layer
[layer_id
].desc
), sizeof(TarkinVideoLayerDesc
));
275 TarkinError
tarkin_synthesis_init (TarkinStream
*s
, TarkinInfo
*ti
)
278 s
->layer
= ti
->layer
; /* It was malloc()ed by headerin() */
279 s
->n_layers
= ti
->n_layers
;
283 TarkinError
tarkin_synthesis_packetin (TarkinStream
*s
, ogg_packet
*op
)
285 uint32_t i
, layer_id
, comp
, data_len
;
286 uint32_t flags
, junk
;
289 TarkinPacket
*packet
;
291 printf("dbg_ogg: Reading packet n° %lld, granulepos %lld, len %ld, %s%s\n",
292 op
->packetno
, op
->granulepos
, op
->bytes
,
293 op
->b_o_s
?"b_o_s":"", op
->e_o_s
?"e_o_s":"");
295 oggpack_readinit(&opb
,op
->packet
,op
->bytes
);
296 flags
= oggpack_read(&opb
,8);
297 layer_id
= oggpack_read(&opb
,12); /* Theses are required for */
298 comp
= oggpack_read(&opb
,12); /* data hole handling (or maybe
299 * packetno would be enough ?) */
302 if(flags
){ /* This is void "infinite future features" feature ;) */
306 junk
= oggpack_read(&opb
,8); /* allow for many future flags
307 that must be correctly ordonned. */
309 /* This shows how to get a feature's data:
310 if (flags & TARKIN_FLAGS_EXAMPLE){
311 tp->example = oggpack_read(&opb,32);
312 junk = tp->example & 3<<30;
313 tp->example &= 0x4fffffff;
316 for(junk
=1<<31;junk
& 1<<31;) /* and many future data */
317 while((junk
=oggpack_read(&opb
,32)) & 1<<30);
318 /* That is, feature data comes in 30 bit chunks. We also have
319 * 31 potentially usefull bits in last chunk. */
322 nread
= (opb
.ptr
- opb
.buffer
);
323 data_len
= op
->bytes
- nread
;
326 printf(" layer_id %d, comp %d, meta-data %dB, w3d data %dB.\n",
327 layer_id
, comp
,nread
, data_len
);
330 /* We now have for shure our data. */
331 packet
= &s
->layer
[layer_id
].packet
[comp
];
332 if(packet
->data_len
)return(-TARKIN_UNUSED
); /* Previous data wasn't used */
334 if(packet
->storage
< data_len
){
335 packet
->storage
= data_len
+ 255;
336 packet
->data
= REALLOC (packet
->data
, packet
->storage
);
339 for(i
=0;i
< data_len
; i
++)
340 packet
->data
[i
] = oggpack_read(&opb
,8);
342 packet
->data_len
= data_len
;
347 TarkinError
tarkin_synthesis_frameout(TarkinStream
*s
,
349 uint32_t layer_id
, TarkinTime
*date
)
352 TarkinVideoLayer
*layer
= &s
->layer
[layer_id
];
353 if (s
->current_frame_in_buf
== 0) {
354 *frame
= MALLOC (layer
->desc
.width
* layer
->desc
.height
* layer
->n_comp
);
355 for (j
=0; j
<layer
->n_comp
; j
++) {
356 TarkinPacket
*packet
= layer
->packet
+ j
;
358 if(packet
->data_len
== 0)goto err_out
;
360 wavelet_3d_buf_decode_coeff (layer
->waveletbuf
[j
], packet
->data
,
363 wavelet_3d_buf_dump ("rcoeff-%d-%03d.pgm",
364 s
->current_frame
, j
, layer
->waveletbuf
[j
],
367 wavelet_3d_buf_inv_xform (layer
->waveletbuf
[j
],
368 layer
->desc
.a_moments
,
369 layer
->desc
.s_moments
);
371 wavelet_3d_buf_dump ("rcolor-%d-%03d.pgm",
373 layer
->waveletbuf
[j
], j
== 0 ? 0 : 128);
376 /* We did successfylly read a block from this layer, acknowledge it. */
377 for (j
=0; j
< layer
->n_comp
; j
++)
378 layer
->packet
[j
].data_len
= 0;
381 layer
->color_inv_xform (layer
->waveletbuf
, *frame
,
382 s
->current_frame_in_buf
);
383 s
->current_frame_in_buf
++;
386 if (s
->current_frame_in_buf
== s
->frames_per_buf
)
387 s
->current_frame_in_buf
=0;
389 date
->numerator
= layer
->frameno
* s
->ti
->inter
.numerator
;
390 date
->denominator
= s
->ti
->inter
.denominator
;
392 printf("dbg_ogg: outputting frame pos %d/%d from layer %d.\n",
393 date
->numerator
, date
->denominator
, layer_id
);
399 return (TARKIN_NEED_MORE
);
402 int tarkin_synthesis_freeframe(TarkinStream
*s
, uint8_t *frame
)