OpenCores
URL https://opencores.org/ocsvn/bluespec-h264/bluespec-h264/trunk

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [test/] [decoder/] [ldecod/] [src/] [output.c] - Blame information for rev 100

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jamey.hick
 
2
/*!
3
 ************************************************************************
4
 * \file output.c
5
 *
6
 * \brief
7
 *    Output an image and Trance support
8
 *
9
 * \author
10
 *    Main contributors (see contributors.h for copyright, address and affiliation details)
11
 *    - Karsten Suehring               <suehring@hhi.de>
12
 ************************************************************************
13
 */
14
 
15
#include "contributors.h"
16
 
17
#include <stdlib.h>
18
#include <assert.h>
19
#include <string.h>
20
 
21
#ifdef WIN32
22
#include <io.h>
23
#else
24
#include <unistd.h>
25
#endif
26
 
27
#include "global.h"
28
#include "mbuffer.h"
29
#include "image.h"
30
#include "memalloc.h"
31
 
32
FrameStore* out_buffer;
33
 
34
StorablePicture *pending_output = NULL;
35
int              pending_output_state = FRAME;
36
int recovery_flag = 0;
37
 
38
extern int non_conforming_stream;
39
 
40
void write_out_picture(StorablePicture *p, int p_out);
41
 
42
 
43
/*!
44
 ************************************************************************
45
 * \brief
46
 *      checks if the System is big- or little-endian
47
 * \return
48
 *      0, little-endian (e.g. Intel architectures)
49
 *      1, big-endian (e.g. SPARC, MIPS, PowerPC)
50
 ************************************************************************
51
 */
52
int testEndian()
53
{
54
  short s;
55
  byte *p;
56
 
57
  p=(byte*)&s;
58
 
59
  s=1;
60
 
61
  return (*p==0);
62
}
63
 
64
 
65
/*!
66
 ************************************************************************
67
 * \brief
68
 *    Convert image plane to temporary buffer for file writing
69
 * \param imgX
70
 *    Pointer to image plane
71
 * \param buf
72
 *    Buffer for file output
73
 * \param size_x
74
 *    horizontal size
75
 * \param size_y
76
 *    vertical size
77
 * \param symbol_size_in_bytes
78
 *    number of bytes used per pel
79
 * \param crop_left
80
 *    pixels to crop from left
81
 * \param crop_right
82
 *    pixels to crop from right
83
 * \param crop_top
84
 *    pixels to crop from top
85
 * \param crop_bottom
86
 *    pixels to crop from bottom
87
 ************************************************************************
88
 */
89
void img2buf (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom)
90
{
91
  int i,j;
92
 
93
  int twidth  = size_x - crop_left - crop_right;
94
  int theight = size_y - crop_top - crop_bottom;
95
 
96
  int size = 0;
97
 
98
  unsigned char  ui8;
99
  unsigned short tmp16, ui16;
100
  unsigned long  tmp32, ui32;
101
 
102
  if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes))
103
  {
104
    // imgpel == pixel_in_file == 1 byte -> simple copy
105
    for(i=0;i<theight;i++)
106
      memcpy(buf+crop_left+(i*twidth),&(imgX[i+crop_top][crop_left]), twidth);
107
 
108
  }
109
  else
110
  {
111
    // sizeof (imgpel) > sizeof(char)
112
    if (testEndian())
113
    {
114
      // big endian
115
      switch (symbol_size_in_bytes)
116
      {
117
      case 1:
118
        {
119
          for(i=crop_top;i<size_y-crop_bottom;i++)
120
            for(j=crop_left;j<size_x-crop_right;j++)
121
            {
122
              ui8 = (unsigned char) (imgX[i][j]);
123
              buf[(j-crop_left+((i-crop_top)*(twidth)))] = ui8;
124
            }
125
          break;
126
        }
127
      case 2:
128
        {
129
          for(i=crop_top;i<size_y-crop_bottom;i++)
130
            for(j=crop_left;j<size_x-crop_right;j++)
131
            {
132
              tmp16 = (unsigned short) (imgX[i][j]);
133
              ui16  = (tmp16 >> 8) | ((tmp16&0xFF)<<8);
134
              memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*2),&(ui16), 2);
135
            }
136
          break;
137
        }
138
      case 4:
139
        {
140
          for(i=crop_top;i<size_y-crop_bottom;i++)
141
            for(j=crop_left;j<size_x-crop_right;j++)
142
            {
143
              tmp32 = (unsigned long) (imgX[i][j]);
144
              ui32  = ((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24);
145
              memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*4),&(ui32), 4);
146
            }
147
          break;
148
        }
149
      default:
150
        {
151
           error ("writing only to formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
152
           break;
153
        }
154
      }
155
 
156
    }
157
    else
158
    {
159
      // little endian
160
      if (sizeof (imgpel) < symbol_size_in_bytes)
161
      {
162
        // this should not happen. we should not have smaller imgpel than our source material.
163
        size = sizeof (imgpel);
164
        // clear buffer
165
        memset (buf, 0, (twidth*theight*symbol_size_in_bytes));
166
      }
167
      else
168
      {
169
        size = symbol_size_in_bytes;
170
      }
171
 
172
      if ((crop_top || crop_bottom || crop_left || crop_right) || (size != 1))
173
      {
174
        for(i=crop_top;i<size_y-crop_bottom;i++)
175
        {
176
          int ipos = (i-crop_top)*(twidth);
177
          for(j=crop_left;j<size_x-crop_right;j++)
178
          {
179
            memcpy(buf+((j-crop_left+(ipos))*symbol_size_in_bytes),&(imgX[i][j]), size);
180
          }
181
        }
182
      }
183
      else
184
      {
185
        for(i=0;i<size_y;i++)
186
        {
187
          for(j=0;j<size_x;j++)
188
          {
189
            *(buf++)=(char) imgX[i][j];
190
          }
191
        }
192
      }
193
    }
194
  }
195
}
196
 
197
 
198
#ifdef PAIR_FIELDS_IN_OUTPUT
199
 
200
void clear_picture(StorablePicture *p);
201
 
202
/*!
203
 ************************************************************************
204
 * \brief
205
 *    output the pending frame buffer
206
 * \param p_out
207
 *    Output file
208
 ************************************************************************
209
 */
210
void flush_pending_output(int p_out)
211
{
212
  if (pending_output_state!=FRAME)
213
  {
214
    write_out_picture(pending_output, p_out);
215
  }
216
 
217
  if (pending_output->imgY)
218
  {
219
    free_mem2Dpel (pending_output->imgY);
220
    pending_output->imgY=NULL;
221
  }
222
  if (pending_output->imgUV)
223
  {
224
    free_mem3Dpel (pending_output->imgUV, 2);
225
    pending_output->imgUV=NULL;
226
  }
227
 
228
  pending_output_state = FRAME;
229
}
230
 
231
 
232
/*!
233
 ************************************************************************
234
 * \brief
235
 *    Writes out a storable picture
236
 *    If the picture is a field, the output buffers the picture and tries
237
 *    to pair it with the next field.
238
 * \param p
239
 *    Picture to be written
240
 * \param p_out
241
 *    Output file
242
 ************************************************************************
243
 */
244
void write_picture(StorablePicture *p, int p_out, int real_structure)
245
{
246
   int i, add;
247
 
248
  if (real_structure==FRAME)
249
  {
250
    flush_pending_output(p_out);
251
    write_out_picture(p, p_out);
252
    return;
253
  }
254
  if (real_structure==pending_output_state)
255
  {
256
    flush_pending_output(p_out);
257
    write_picture(p, p_out, real_structure);
258
    return;
259
  }
260
 
261
  if (pending_output_state == FRAME)
262
  {
263
    pending_output->size_x = p->size_x;
264
    pending_output->size_y = p->size_y;
265
    pending_output->size_x_cr = p->size_x_cr;
266
    pending_output->size_y_cr = p->size_y_cr;
267
    pending_output->chroma_format_idc = p->chroma_format_idc;
268
 
269
    pending_output->frame_mbs_only_flag = p->frame_mbs_only_flag;
270
    pending_output->frame_cropping_flag = p->frame_cropping_flag;
271
    if (pending_output->frame_cropping_flag)
272
    {
273
      pending_output->frame_cropping_rect_left_offset = p->frame_cropping_rect_left_offset;
274
      pending_output->frame_cropping_rect_right_offset = p->frame_cropping_rect_right_offset;
275
      pending_output->frame_cropping_rect_top_offset = p->frame_cropping_rect_top_offset;
276
      pending_output->frame_cropping_rect_bottom_offset = p->frame_cropping_rect_bottom_offset;
277
    }
278
 
279
    get_mem2Dpel (&(pending_output->imgY), pending_output->size_y, pending_output->size_x);
280
    get_mem3Dpel (&(pending_output->imgUV), 2, pending_output->size_y_cr, pending_output->size_x_cr);
281
 
282
    clear_picture(pending_output);
283
 
284
    // copy first field
285
    if (real_structure == TOP_FIELD)
286
    {
287
      add = 0;
288
    }
289
    else
290
    {
291
      add = 1;
292
    }
293
 
294
    for (i=0; i<pending_output->size_y; i+=2)
295
    {
296
      memcpy(pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x * sizeof(imgpel));
297
    }
298
    for (i=0; i<pending_output->size_y_cr; i+=2)
299
    {
300
      memcpy(pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr * sizeof(imgpel));
301
      memcpy(pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr * sizeof(imgpel));
302
    }
303
    pending_output_state = real_structure;
304
  }
305
  else
306
  {
307
    if (  (pending_output->size_x!=p->size_x) || (pending_output->size_y!= p->size_y)
308
       || (pending_output->frame_mbs_only_flag != p->frame_mbs_only_flag)
309
       || (pending_output->frame_cropping_flag != p->frame_cropping_flag)
310
       || ( pending_output->frame_cropping_flag &&
311
            (  (pending_output->frame_cropping_rect_left_offset   != p->frame_cropping_rect_left_offset)
312
             ||(pending_output->frame_cropping_rect_right_offset  != p->frame_cropping_rect_right_offset)
313
             ||(pending_output->frame_cropping_rect_top_offset    != p->frame_cropping_rect_top_offset)
314
             ||(pending_output->frame_cropping_rect_bottom_offset != p->frame_cropping_rect_bottom_offset)
315
            )
316
          )
317
       )
318
    {
319
      flush_pending_output(p_out);
320
      write_picture (p, p_out, real_structure);
321
      return;
322
    }
323
    // copy second field
324
    if (real_structure == TOP_FIELD)
325
    {
326
      add = 0;
327
    }
328
    else
329
    {
330
      add = 1;
331
    }
332
 
333
    for (i=0; i<pending_output->size_y; i+=2)
334
    {
335
      memcpy(pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x * sizeof(imgpel));
336
    }
337
    for (i=0; i<pending_output->size_y_cr; i+=2)
338
    {
339
      memcpy(pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr * sizeof(imgpel));
340
      memcpy(pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr * sizeof(imgpel));
341
    }
342
 
343
    flush_pending_output(p_out);
344
  }
345
}
346
 
347
#else
348
 
349
/*!
350
 ************************************************************************
351
 * \brief
352
 *    Writes out a storable picture without doing any output modifications
353
 * \param p
354
 *    Picture to be written
355
 * \param p_out
356
 *    Output file
357
 * \param real_structure
358
 *    real picture structure
359
 ************************************************************************
360
 */
361
void write_picture(StorablePicture *p, int p_out, int real_structure)
362
{
363
  write_out_picture(p, p_out);
364
}
365
 
366
 
367
#endif
368
 
369
/*!
370
************************************************************************
371
* \brief
372
*    Writes out a storable picture
373
* \param p
374
*    Picture to be written
375
* \param p_out
376
*    Output file
377
************************************************************************
378
*/
379
void write_out_picture(StorablePicture *p, int p_out)
380
{
381
  int SubWidthC  [4]= { 1, 2, 2, 1};
382
  int SubHeightC [4]= { 1, 2, 1, 1};
383
 
384
  int crop_left, crop_right, crop_top, crop_bottom;
385
  int symbol_size_in_bytes = img->pic_unit_bitsize_on_disk/8;
386
  Boolean rgb_output = (Boolean) (active_sps->vui_seq_parameters.matrix_coefficients==0);
387
  unsigned char *buf;
388
 
389
  if (p->non_existing)
390
    return;
391
 
392
  if (p->frame_cropping_flag)
393
  {
394
    crop_left   = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
395
    crop_right  = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
396
    crop_top    = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
397
    crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
398
  }
399
  else
400
  {
401
    crop_left = crop_right = crop_top = crop_bottom = 0;
402
  }
403
 
404
  //printf ("write frame size: %dx%d\n", p->size_x-crop_left-crop_right,p->size_y-crop_top-crop_bottom );
405
 
406
  // KS: this buffer should actually be allocated only once, but this is still much faster than the previous version
407
  buf = malloc (p->size_x*p->size_y*symbol_size_in_bytes);
408
  if (NULL==buf)
409
  {
410
    no_mem_exit("write_out_picture: buf");
411
  }
412
 
413
  if(rgb_output)
414
  {
415
    crop_left   = p->frame_cropping_rect_left_offset;
416
    crop_right  = p->frame_cropping_rect_right_offset;
417
    crop_top    = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
418
    crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
419
 
420
    img2buf (p->imgUV[1], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
421
    write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
422
 
423
    if (p->frame_cropping_flag)
424
    {
425
      crop_left   = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
426
      crop_right  = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
427
      crop_top    = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
428
      crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
429
    }
430
    else
431
    {
432
      crop_left = crop_right = crop_top = crop_bottom = 0;
433
    }
434
  }
435
 
436
  img2buf (p->imgY, buf, p->size_x, p->size_y, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
437
  write(p_out, buf, (p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes);
438
 
439
  if (p->chroma_format_idc!=YUV400)
440
  {
441
    crop_left   = p->frame_cropping_rect_left_offset;
442
    crop_right  = p->frame_cropping_rect_right_offset;
443
    crop_top    = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
444
    crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
445
 
446
    img2buf (p->imgUV[0], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
447
    write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)* symbol_size_in_bytes);
448
 
449
    if (!rgb_output)
450
    {
451
      img2buf (p->imgUV[1], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
452
      write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
453
    }
454
  }
455
  else
456
  {
457
    if (input->write_uv)
458
    {
459
      int i,j;
460
      imgpel cr_val = (imgpel) (1<<(img->bitdepth_luma - 1));
461
 
462
      get_mem3Dpel (&(p->imgUV), 1, p->size_y/2, p->size_x/2);
463
      for (j=0; j<p->size_y/2; j++)
464
        for (i=0; i<p->size_x/2; i++)
465
          p->imgUV[0][j][i]=cr_val;
466
 
467
      // fake out U=V=128 to make a YUV 4:2:0 stream
468
      img2buf (p->imgUV[0], buf, p->size_x/2, p->size_y/2, symbol_size_in_bytes, crop_left/2, crop_right/2, crop_top/2, crop_bottom/2);
469
 
470
      write(p_out, buf, symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2 );
471
      write(p_out, buf, symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2 );
472
 
473
      free_mem3Dpel(p->imgUV, 1);
474
      p->imgUV=NULL;
475
    }
476
  }
477
 
478
  free(buf);
479
 
480
//  fsync(p_out);
481
}
482
 
483
/*!
484
 ************************************************************************
485
 * \brief
486
 *    Initialize output buffer for direct output
487
 ************************************************************************
488
 */
489
void init_out_buffer()
490
{
491
  out_buffer = alloc_frame_store();
492
#ifdef PAIR_FIELDS_IN_OUTPUT
493
  pending_output = calloc (sizeof(StorablePicture), 1);
494
  if (NULL==pending_output) no_mem_exit("init_out_buffer");
495
  pending_output->imgUV = NULL;
496
  pending_output->imgY  = NULL;
497
#endif
498
}
499
 
500
/*!
501
 ************************************************************************
502
 * \brief
503
 *    Uninitialize output buffer for direct output
504
 ************************************************************************
505
 */
506
void uninit_out_buffer()
507
{
508
  free_frame_store(out_buffer);
509
  out_buffer=NULL;
510
#ifdef PAIR_FIELDS_IN_OUTPUT
511
  flush_pending_output(p_out);
512
  free (pending_output);
513
#endif
514
}
515
 
516
/*!
517
 ************************************************************************
518
 * \brief
519
 *    Initialize picture memory with (Y:0,U:128,V:128)
520
 ************************************************************************
521
 */
522
void clear_picture(StorablePicture *p)
523
{
524
  int i,j;
525
 
526
  for(i=0;i<p->size_y;i++)
527
  {
528
    for (j=0; j<p->size_x; j++)
529
      p->imgY[i][j] = (imgpel) img->dc_pred_value_luma;
530
  }
531
  for(i=0;i<p->size_y_cr;i++)
532
  {
533
    for (j=0; j<p->size_x_cr; j++)
534
      p->imgUV[0][i][j] = (imgpel) img->dc_pred_value_chroma;
535
  }
536
  for(i=0;i<p->size_y_cr;i++)
537
  {
538
    for (j=0; j<p->size_x_cr; j++)
539
      p->imgUV[1][i][j] = (imgpel) img->dc_pred_value_chroma;
540
  }
541
 
542
}
543
 
544
/*!
545
 ************************************************************************
546
 * \brief
547
 *    Write out not paired direct output fields. A second empty field is generated
548
 *    and combined into the frame buffer.
549
 * \param fs
550
 *    FrameStore that contains a single field
551
 * \param p_out
552
 *    Output file
553
 ************************************************************************
554
 */
555
void write_unpaired_field(FrameStore* fs, int p_out)
556
{
557
  StorablePicture *p;
558
  assert (fs->is_used<3);
559
  if(fs->is_used &1)
560
  {
561
    // we have a top field
562
    // construct an empty bottom field
563
    p = fs->top_field;
564
    fs->bottom_field = alloc_storable_picture(BOTTOM_FIELD, p->size_x, 2*p->size_y, p->size_x_cr, 2*p->size_y_cr);
565
    fs->bottom_field->chroma_format_idc = p->chroma_format_idc;
566
    clear_picture(fs->bottom_field);
567
    dpb_combine_field_yuv(fs);
568
    write_picture (fs->frame, p_out, TOP_FIELD);
569
  }
570
 
571
  if(fs->is_used &2)
572
  {
573
    // we have a bottom field
574
    // construct an empty top field
575
    p = fs->bottom_field;
576
    fs->top_field = alloc_storable_picture(TOP_FIELD, p->size_x, 2*p->size_y, p->size_x_cr, 2*p->size_y_cr);
577
    fs->top_field->chroma_format_idc = p->chroma_format_idc;
578
    clear_picture(fs->top_field);
579
    fs ->top_field->frame_cropping_flag = fs->bottom_field->frame_cropping_flag;
580
    if(fs ->top_field->frame_cropping_flag)
581
    {
582
      fs ->top_field->frame_cropping_rect_top_offset = fs->bottom_field->frame_cropping_rect_top_offset;
583
      fs ->top_field->frame_cropping_rect_bottom_offset = fs->bottom_field->frame_cropping_rect_bottom_offset;
584
      fs ->top_field->frame_cropping_rect_left_offset = fs->bottom_field->frame_cropping_rect_left_offset;
585
      fs ->top_field->frame_cropping_rect_right_offset = fs->bottom_field->frame_cropping_rect_right_offset;
586
    }
587
    dpb_combine_field_yuv(fs);
588
    write_picture (fs->frame, p_out, BOTTOM_FIELD);
589
  }
590
 
591
  fs->is_used=3;
592
}
593
 
594
/*!
595
 ************************************************************************
596
 * \brief
597
 *    Write out unpaired fields from output buffer.
598
 * \param p_out
599
 *    Output file
600
 ************************************************************************
601
 */
602
void flush_direct_output(int p_out)
603
{
604
  write_unpaired_field(out_buffer, p_out);
605
 
606
  free_storable_picture(out_buffer->frame);
607
  out_buffer->frame = NULL;
608
  free_storable_picture(out_buffer->top_field);
609
  out_buffer->top_field = NULL;
610
  free_storable_picture(out_buffer->bottom_field);
611
  out_buffer->bottom_field = NULL;
612
  out_buffer->is_used = 0;
613
}
614
 
615
 
616
/*!
617
 ************************************************************************
618
 * \brief
619
 *    Write a frame (from FrameStore)
620
 * \param fs
621
 *    FrameStore containing the frame
622
 * \param p_out
623
 *    Output file
624
 ************************************************************************
625
 */
626
void write_stored_frame( FrameStore *fs,int p_out)
627
{
628
  // make sure no direct output field is pending
629
  flush_direct_output(p_out);
630
 
631
  if (fs->is_used<3)
632
  {
633
    write_unpaired_field(fs, p_out);
634
  }
635
  else
636
  {
637
    if (fs->recovery_frame)
638
      recovery_flag = 1;
639
    if ((!non_conforming_stream) || recovery_flag)
640
      write_picture(fs->frame, p_out, FRAME);
641
  }
642
 
643
  fs->is_output = 1;
644
}
645
 
646
/*!
647
 ************************************************************************
648
 * \brief
649
 *    Directly output a picture without storing it in the DPB. Fields
650
 *    are buffered before they are written to the file.
651
 * \param p
652
 *    Picture for output
653
 * \param p_out
654
 *    Output file
655
 ************************************************************************
656
 */
657
void direct_output(StorablePicture *p, int p_out)
658
{
659
  if (p->structure==FRAME)
660
  {
661
    // we have a frame (or complementary field pair)
662
    // so output it directly
663
    flush_direct_output(p_out);
664
    write_picture (p, p_out, FRAME);
665
    if (-1!=p_ref && !input->silent)
666
      find_snr(snr, p, p_ref);
667
    free_storable_picture(p);
668
    return;
669
  }
670
 
671
  if (p->structure == TOP_FIELD)
672
  {
673
    if (out_buffer->is_used &1)
674
      flush_direct_output(p_out);
675
    out_buffer->top_field = p;
676
    out_buffer->is_used |= 1;
677
  }
678
 
679
  if (p->structure == BOTTOM_FIELD)
680
  {
681
    if (out_buffer->is_used &2)
682
      flush_direct_output(p_out);
683
    out_buffer->bottom_field = p;
684
    out_buffer->is_used |= 2;
685
  }
686
 
687
  if (out_buffer->is_used == 3)
688
  {
689
    // we have both fields, so output them
690
    dpb_combine_field_yuv(out_buffer);
691
    write_picture (out_buffer->frame, p_out, FRAME);
692
    if (-1!=p_ref && !input->silent)
693
      find_snr(snr, out_buffer->frame, p_ref);
694
    free_storable_picture(out_buffer->frame);
695
    out_buffer->frame = NULL;
696
    free_storable_picture(out_buffer->top_field);
697
    out_buffer->top_field = NULL;
698
    free_storable_picture(out_buffer->bottom_field);
699
    out_buffer->bottom_field = NULL;
700
    out_buffer->is_used = 0;
701
  }
702
}
703
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.