igor ru.po
[goodguy/history.git] / cinelerra-5.1 / libzmpeg3 / video / getpicture.C
1 #include "../libzmpeg3.h"
2
3 zslice_buffer_t *zvideo_t::
4 get_slice_buffer()
5 {
6   slice_lock.lock();
7   while( avail_slice_buffers == 0 ) {
8     ++slice_wait_locked;
9     slice_lock.unlock();
10     slice_wait.lock();
11     slice_lock.lock();
12   }
13   zslice_buffer_t *buffer = avail_slice_buffers;
14   avail_slice_buffers = buffer->next;
15   buffer->video = this;
16   buffer->buffer_position = 0;
17   buffer->bits_size = 0;
18   buffer->buffer_size = 0;
19   if( !slice_active_locked++ )
20     slice_active.lock();
21   slice_lock.unlock();
22   return buffer;
23 }
24
25 void zvideo_t::
26 put_slice_buffer(zslice_buffer_t* buffer)
27 {
28   slice_lock.lock();
29   buffer->next = avail_slice_buffers;
30   avail_slice_buffers = buffer;
31   if( slice_wait_locked ) {
32     --slice_wait_locked;
33     slice_wait.unlock();
34   }
35   if( !--slice_active_locked )
36     slice_active.unlock();
37   slice_lock.unlock();
38 }
39
40
41 /* decode all macroblocks of the current picture */
42 int zvideo_t::
43 get_macroblocks()
44 {
45   uint32_t zcode;
46 /* Load every slice into a buffer array */
47   while( !eof() ) {
48     zcode = vstream->show_bits32_noptr();
49     if( zcode < SLICE_MIN_START || zcode > SLICE_MAX_START ) break;
50     zslice_buffer_t *slice = get_slice_buffer();
51     slice->fill_buffer(vstream);
52     src->decode_slice(slice);
53   }
54   slice_active.lock();
55   slice_active.unlock();
56   return 0;
57 }
58
59 int zvideo_t::
60 display_second_field()
61 {
62   return 0; /* Not used */
63 }
64
65 /* decode one frame or field picture */
66
67 int zvideo_t::
68 get_picture()
69 {
70   uint8_t **ip_frame;
71   if( pict_type != pic_type_B ) {
72     if( !secondfield ) {
73       for( int i=0; i<3; ++i ) {
74         /* Swap refframes */
75         uint8_t *tmp = oldrefframe[i];
76         oldrefframe[i] = refframe[i];
77         refframe[i] = tmp;
78       }
79     }
80     ip_frame = refframe;
81   }
82   else
83     ip_frame = auxframe;
84
85   for( int i=0; i<3; ++i )
86     newframe[i] = ip_frame[i];
87
88   if( pict_struct == pics_BOTTOM_FIELD ) {
89     newframe[0] += coded_picture_width;
90     newframe[1] += chrom_width;
91     newframe[2] += chrom_width;
92   }
93
94   if( src->cpus != src->total_slice_decoders )
95     src->reallocate_slice_decoders();
96   if( 2*src->cpus != total_slice_buffers )
97     reallocate_slice_buffers();
98
99   int result = get_macroblocks();
100
101   /* Set the frame to display */
102   output_src[0] = output_src[1] = output_src[2] = 0;
103
104   if( !result && thumb ) {
105     switch( pict_type ) {
106     case pic_type_P:
107       if( !ithumb ) break;
108       ithumb = 0;
109       src->thumbnail_fn(src->thumbnail_priv, track->number);
110       break;
111     case pic_type_I:
112       ithumb = 1;
113       break;
114     }
115   }
116   if( !result && !skim && framenum >= 0 ) {
117     if( pict_struct == pics_FRAME_PICTURE || secondfield ) {
118       if( pict_type == pic_type_B ) {
119         output_src[0] = auxframe[0];
120         output_src[1] = auxframe[1];
121         output_src[2] = auxframe[2];
122       }
123       else {
124         output_src[0] = oldrefframe[0];
125         output_src[1] = oldrefframe[1];
126         output_src[2] = oldrefframe[2];
127       }
128     }
129     else {
130       display_second_field();
131     }
132   }
133
134   return result;
135 }
136