www.pudn.com > jm74.zip > output.c
/*! ************************************************************************ * \file output.c * * \brief * Output an image and Trance support * * \author * Main contributors (see contributors.h for copyright, address and affiliation details) * - Karsten Suehring************************************************************************ */ #include "contributors.h" #include #include #include #include "global.h" #include "mbuffer.h" #include "image.h" FrameStore* out_buffer; /*! ************************************************************************ * \brief * Writes out a storable picture * \param p * Picture to be written * \param p_out * Output file ************************************************************************ */ void write_picture(StorablePicture *p, FILE *p_out) { int i,j; int crop_left, crop_right, crop_top, crop_bottom; int crop_vert_mult; if (active_sps->frame_mbs_only_flag) { crop_vert_mult = 2; } else { if (p->structure != FRAME) { crop_vert_mult = 2; } else { crop_vert_mult = 4; } } if (active_sps->frame_cropping_flag) { crop_left = 2 * active_sps->frame_cropping_rect_left_offset; crop_right = 2 * active_sps->frame_cropping_rect_right_offset; crop_top = crop_vert_mult * active_sps->frame_cropping_rect_top_offset; crop_bottom = crop_vert_mult * active_sps->frame_cropping_rect_bottom_offset; } else { crop_left = crop_right = crop_top = crop_bottom = 0; } for(i=crop_top;i size_y-crop_bottom;i++) for(j=crop_left;j size_x-crop_right;j++) { fputc(p->imgY[i][j],p_out); } crop_left /= 2; crop_right /= 2; crop_top /= 2; crop_bottom /= 2; for(i=crop_top;i size_y_cr-crop_bottom;i++) for(j=crop_left;j size_x_cr-crop_right;j++) { fputc(p->imgUV[0][i][j],p_out); } for(i=crop_top;i size_y_cr-crop_bottom;i++) for(j=crop_left;j size_x_cr-crop_right;j++) { fputc(p->imgUV[1][i][j],p_out); } fflush(p_out); } /*! ************************************************************************ * \brief * Initialize output buffer for direct output ************************************************************************ */ void init_out_buffer() { out_buffer = alloc_frame_store(); } /*! ************************************************************************ * \brief * Uninitialize output buffer for direct output ************************************************************************ */ void uninit_out_buffer() { free_frame_store(out_buffer); out_buffer=NULL; } /*! ************************************************************************ * \brief * Initialize picture memory with (Y:0,U:128,V:128) ************************************************************************ */ void clear_picture(StorablePicture *p) { int i; for(i=0;i size_y;i++) memset(p->imgY[i], 0 ,p->size_x); for(i=0;i size_y_cr;i++) memset(p->imgUV[0][i], 128 ,p->size_x_cr); for(i=0;i size_y_cr;i++) memset(p->imgUV[1][i], 128 ,p->size_x_cr); fflush(p_out); } /*! ************************************************************************ * \brief * Write out not paired direct output fields. A second empty field is generated * and combined into the frame buffer. * \param fs * FrameStore that contains a single field * \param p_out * Output file ************************************************************************ */ void write_unpaired_field(FrameStore* fs, FILE *p_out) { StorablePicture *p; assert (fs->is_used<3); if(fs->is_used &1) { // we have a top field // construct an empty bottom field p = fs->top_field; fs->bottom_field = alloc_storable_picture(BOTTOM_FIELD, p->size_x, p->size_y, p->size_x_cr, p->size_y_cr); clear_picture(fs->bottom_field); dpb_combine_field(fs); write_picture (fs->frame, p_out); fs->is_used=3; } if(fs->is_used &2) { // we have a bottom field // construct an empty top field p = fs->bottom_field; fs->top_field = alloc_storable_picture(TOP_FIELD, p->size_x, p->size_y, p->size_x_cr, p->size_y_cr); clear_picture(fs->bottom_field); dpb_combine_field(fs); write_picture (fs->frame, p_out); fs->is_used=3; } } /*! ************************************************************************ * \brief * Write out unpaired fields from output buffer. * \param p_out * Output file ************************************************************************ */ void flush_direct_output(FILE *p_out) { write_unpaired_field(out_buffer, p_out); free_storable_picture(out_buffer->frame); out_buffer->frame = NULL; free_storable_picture(out_buffer->top_field); out_buffer->top_field = NULL; free_storable_picture(out_buffer->bottom_field); out_buffer->bottom_field = NULL; out_buffer->is_used = 0; } /*! ************************************************************************ * \brief * Write a frame (from FrameStore) * \param fs * FrameStore containing the frame * \param p_out * Output file ************************************************************************ */ void write_stored_frame( FrameStore *fs,FILE *p_out) { // make sure no direct output field is pending flush_direct_output(p_out); if (fs->is_used<3) { write_unpaired_field(fs, p_out); } else { write_picture(fs->frame, p_out); } fs->is_output = 1; } /*! ************************************************************************ * \brief * Directly output a picture without storing it in the DPB. Fields * are buffered before they are written to the file. * \param p * Picture for output * \param p_out * Output file ************************************************************************ */ void direct_output(StorablePicture *p, FILE *p_out) { if (p->structure==FRAME) { // we have a frame (or complementary field pair) // so output it directly flush_direct_output(p_out); write_picture (p, p_out); if (p_ref) find_snr(snr, p, p_ref); free_storable_picture(p); return; } if (p->structure == TOP_FIELD) { if (out_buffer->is_used &1) flush_direct_output(p_out); out_buffer->top_field = p; out_buffer->is_used |= 1; } if (p->structure == BOTTOM_FIELD) { if (out_buffer->is_used &2) flush_direct_output(p_out); out_buffer->bottom_field = p; out_buffer->is_used |= 2; } if (out_buffer->is_used == 3) { // we have both fields, so output them dpb_combine_field(out_buffer); write_picture (out_buffer->frame, p_out); if (p_ref) find_snr(snr, out_buffer->frame, p_ref); free_storable_picture(out_buffer->frame); out_buffer->frame = NULL; free_storable_picture(out_buffer->top_field); out_buffer->top_field = NULL; free_storable_picture(out_buffer->bottom_field); out_buffer->bottom_field = NULL; out_buffer->is_used = 0; } }