Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

mash.cpp

00001 /*****************************************************************************
00002  * mash.c: Video decoder using openmash codec implementations
00003  *****************************************************************************
00004  * Copyright (C) 2004 the VideoLAN team
00005  * $Id: mash.cpp 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Sigmund Augdal <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <vlc/vlc.h>
00028 #include <vlc/decoder.h>
00029 #include <vlc/vout.h>
00030 
00031 #include <p64/p64.h>
00032 
00033 /*****************************************************************************
00034  * decoder_sys_t : video decoder descriptor
00035  *****************************************************************************/
00036 struct decoder_sys_t
00037 {
00038     /*
00039      * Common properties
00040      */
00041     mtime_t i_pts;
00042     IntraP64Decoder *p_decoder;
00043     vlc_bool_t b_inited;
00044     int i_counter;
00045 
00046 };
00047 
00048 /****************************************************************************
00049  * Local prototypes
00050  ****************************************************************************/
00051 static int  OpenDecoder   ( vlc_object_t * );
00052 static void CloseDecoder  ( vlc_object_t * );
00053 
00054 static void *DecodeBlock  ( decoder_t *, block_t ** );
00055 
00056 #if 0
00057 static picture_t *DecodeFrame( decoder_t *, block_t * );
00058 static block_t   *SendFrame  ( decoder_t *, block_t * );
00059 #endif
00060 
00061 /*****************************************************************************
00062  * Module descriptor
00063  *****************************************************************************/
00064 vlc_module_begin();
00065     set_description( _("Video decoder using openmash") );
00066     set_capability( "decoder", 50 );
00067     set_category( CAT_INPUT );
00068     set_subcategory( SUBCAT_INPUT_VCODEC );
00069     set_callbacks( OpenDecoder, CloseDecoder );
00070 vlc_module_end();
00071 
00072 /*****************************************************************************
00073  * OpenDecoder: probe the decoder and return score
00074  *****************************************************************************/
00075 static int OpenDecoder( vlc_object_t *p_this )
00076 {
00077     decoder_t *p_dec = (decoder_t*)p_this;
00078     decoder_sys_t *p_sys;
00079 
00080     switch( p_dec->fmt_in.i_codec )
00081     {
00082         /* Planar YUV */
00083         case VLC_FOURCC('h','2','6','1'):
00084         case VLC_FOURCC('H','2','6','1'):
00085             break;
00086 
00087         default:
00088             return VLC_EGENERIC;
00089     }
00090 
00091     /* Allocate the memory needed to store the decoder's structure */
00092     if( ( p_dec->p_sys = p_sys =
00093           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
00094     {
00095         msg_Err( p_dec, "out of memory" );
00096         return VLC_EGENERIC;
00097     }
00098     /* Misc init */
00099     p_sys->i_pts = 0;
00100     p_sys->b_inited = VLC_FALSE;
00101     p_sys->i_counter = 0;
00102 
00103     /* Set output properties */
00104     p_dec->fmt_out.i_cat = VIDEO_ES;
00105     p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
00106 
00107     /* Set callbacks */
00108     p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
00109         DecodeBlock;
00110     p_sys->p_decoder = new IntraP64Decoder();
00111 //     foo->sync();
00112 
00113     return VLC_SUCCESS;
00114 }
00115 
00116 /*****************************************************************************
00117  * CloseDecoder: decoder destruction
00118  *****************************************************************************/
00119 static void CloseDecoder( vlc_object_t *p_this )
00120 {
00121     decoder_t *p_dec = (decoder_t*)p_this;
00122     free( p_dec->p_sys );
00123 }
00124 
00125 
00126 /****************************************************************************
00127  * DecodeBlock: the whole thing
00128  ****************************************************************************
00129  * This function must be fed with complete frames.
00130  ****************************************************************************/
00131 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
00132 {
00133     decoder_sys_t *p_sys = p_dec->p_sys;
00134     block_t *p_block;
00135     picture_t *p_pic;
00136     uint32_t i_video_header;
00137     uint8_t *p_frame;
00138     int cc, sbit, ebit, mba, gob, quant, mvdh, mvdv;
00139     int i_width, i_height;
00140 
00141     if( !pp_block || !*pp_block ) return NULL;
00142 
00143     p_block = *pp_block;
00144 
00145     if( !p_sys->i_pts && !p_block->i_pts && !p_block->i_dts )
00146     {
00147         /* We've just started the stream, wait for the first PTS. */
00148         block_Release( p_block );
00149         return NULL;
00150     }
00151 
00152 
00153     /* Date management */
00154     if( p_block->i_pts > 0 || p_block->i_dts > 0 )
00155     {
00156         if( p_block->i_pts > 0 ) p_sys->i_pts = p_block->i_pts;
00157         else if( p_block->i_dts > 0 ) p_sys->i_pts = p_block->i_dts;
00158     }
00159 
00160     i_video_header = *(uint32_t*)p_block->p_buffer; /* yes, it is native endian */
00161     sbit = i_video_header >> 29; /* start bit position */
00162     ebit = (i_video_header >> 26) & 7; /* end bit position */
00163     msg_Dbg( p_dec, "sbit, ebit: %d,%d", sbit, ebit );
00164     gob = (i_video_header >> 20) & 0xf; /* GOB number */
00165     if( gob > 12 )
00166     {
00167         msg_Warn( p_dec, "invalid gob, buggy vic streamer?");
00168     }
00169     mba = (i_video_header >> 15) & 0x1f; /* Macroblock address predictor */
00170     quant = (i_video_header >> 10) & 0x1f; /* quantizer */
00171     mvdh = (i_video_header >> 5) & 0x1f; /* horizontal motion vector data */
00172     mvdv = i_video_header & 0x1f; /* vertical motion vector data */
00173     cc = p_block->i_buffer - 4;
00174     msg_Dbg( p_dec, "packet size %d", cc );
00175     
00176     /* Find out p_vdec->i_raw_size */
00177     p_sys->p_decoder->decode( p_block->p_buffer + 4 /*bp?*/,
00178                               cc /*cc?*/,
00179                               sbit /*sbit?*/,
00180                               ebit /*ebit?*/,
00181                               mba /* mba?*/,
00182                               gob /* gob?*/,
00183                               quant /* quant?*/,
00184                               mvdh /* mvdh?*/,
00185                               mvdv /* mvdv?*/ );
00186     i_width = p_sys->p_decoder->width();
00187     i_height = p_sys->p_decoder->height();
00188     if( !p_sys->b_inited )
00189     {
00190         msg_Dbg( p_dec, "video size is perhaps %dx%d", i_width,
00191                   i_height);
00192         vout_InitFormat( &p_dec->fmt_out.video, VLC_FOURCC('I','4','2','0'),
00193                          i_width, i_height,
00194                          VOUT_ASPECT_FACTOR * i_width / i_height );
00195         p_sys->b_inited = VLC_TRUE;
00196     }
00197     p_pic = NULL;
00198     p_sys->i_counter++;
00199 //    p_sys->p_decoder->sync();
00200     if( p_block->i_flags & BLOCK_FLAG_END_OF_FRAME )
00201     {
00202         p_pic = p_dec->pf_vout_buffer_new( p_dec );
00203         if( !p_pic )
00204         {
00205             block_Release( p_block );
00206             return NULL;
00207         }
00208         p_sys->p_decoder->sync();
00209         p_sys->i_counter = 0;
00210         p_frame = p_sys->p_decoder->frame();
00211         p_dec->p_vlc->pf_memcpy( p_pic->p[0].p_pixels, p_frame, i_width*i_height );
00212         p_frame += i_width * i_height;
00213         p_dec->p_vlc->pf_memcpy( p_pic->p[1].p_pixels, p_frame, i_width*i_height/4 );
00214         p_frame += i_width * i_height/4;
00215         p_dec->p_vlc->pf_memcpy( p_pic->p[2].p_pixels, p_frame, i_width*i_height/4 );
00216         p_pic->date = p_sys->i_pts;
00217     }
00218     block_Release( p_block);
00219     *pp_block = NULL;
00220     return p_pic;
00221 //    return NULL;
00222 }

Generated on Tue Dec 20 10:14:29 2005 for vlc-0.8.4a by  doxygen 1.4.2