mash.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:8k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mash.c: Video decoder using openmash codec implementations
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 the VideoLAN team
  5.  * $Id: 88533cb4796230bc183ea3fe6473c73ca3625648 $
  6.  *
  7.  * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <vlc_common.h>
  30. #include <vlc_plugin.h>
  31. #include <vlc_codec.h>
  32. #include <vlc_vout.h>
  33. #include <vlc_block.h>
  34. #include <p64/p64.h>
  35. /*****************************************************************************
  36.  * decoder_sys_t : video decoder descriptor
  37.  *****************************************************************************/
  38. struct decoder_sys_t
  39. {
  40.     /*
  41.      * Common properties
  42.      */
  43.     mtime_t i_pts;
  44.     IntraP64Decoder *p_decoder;
  45.     bool b_inited;
  46.     int i_counter;
  47. };
  48. /****************************************************************************
  49.  * Local prototypes
  50.  ****************************************************************************/
  51. static int  OpenDecoder   ( vlc_object_t * );
  52. static void CloseDecoder  ( vlc_object_t * );
  53. static void *DecodeBlock  ( decoder_t *, block_t ** );
  54. #if 0
  55. static picture_t *DecodeFrame( decoder_t *, block_t * );
  56. static block_t   *SendFrame  ( decoder_t *, block_t * );
  57. #endif
  58. /*****************************************************************************
  59.  * Module descriptor
  60.  *****************************************************************************/
  61. vlc_module_begin ()
  62.     set_description( N_("Video decoder using openmash") )
  63.     set_capability( "decoder", 50 )
  64.     set_category( CAT_INPUT )
  65.     set_subcategory( SUBCAT_INPUT_VCODEC )
  66.     set_callbacks( OpenDecoder, CloseDecoder )
  67. vlc_module_end ()
  68. /*****************************************************************************
  69.  * OpenDecoder: probe the decoder and return score
  70.  *****************************************************************************/
  71. static int OpenDecoder( vlc_object_t *p_this )
  72. {
  73.     decoder_t *p_dec = (decoder_t*)p_this;
  74.     decoder_sys_t *p_sys;
  75.     switch( p_dec->fmt_in.i_codec )
  76.     {
  77.         /* Planar YUV */
  78.         case VLC_FOURCC('h','2','6','1'):
  79.         case VLC_FOURCC('H','2','6','1'):
  80.             break;
  81.         default:
  82.             return VLC_EGENERIC;
  83.     }
  84.     /* Allocate the memory needed to store the decoder's structure */
  85.     if( ( p_dec->p_sys = p_sys =
  86.           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
  87.         return VLC_ENOMEM;
  88.     /* Misc init */
  89.     p_sys->i_pts = 0;
  90.     p_sys->b_inited = false;
  91.     p_sys->i_counter = 0;
  92.     /* Set output properties */
  93.     p_dec->fmt_out.i_cat = VIDEO_ES;
  94.     p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
  95.     /* Set callbacks */
  96.     p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
  97.         DecodeBlock;
  98.     p_sys->p_decoder = new IntraP64Decoder();
  99. //     foo->sync();
  100.     return VLC_SUCCESS;
  101. }
  102. /*****************************************************************************
  103.  * CloseDecoder: decoder destruction
  104.  *****************************************************************************/
  105. static void CloseDecoder( vlc_object_t *p_this )
  106. {
  107.     decoder_t *p_dec = (decoder_t*)p_this;
  108.     free( p_dec->p_sys );
  109. }
  110. /****************************************************************************
  111.  * DecodeBlock: the whole thing
  112.  ****************************************************************************
  113.  * This function must be fed with complete frames.
  114.  ****************************************************************************/
  115. static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
  116. {
  117.     decoder_sys_t *p_sys = p_dec->p_sys;
  118.     block_t *p_block;
  119.     picture_t *p_pic;
  120.     uint32_t i_video_header;
  121.     uint8_t *p_frame;
  122.     int cc, sbit, ebit, mba, gob, quant, mvdh, mvdv;
  123.     int i_width, i_height;
  124.     if( !pp_block || !*pp_block ) return NULL;
  125.     p_block = *pp_block;
  126.     if( !p_sys->i_pts && !p_block->i_pts && !p_block->i_dts )
  127.     {
  128.         /* We've just started the stream, wait for the first PTS. */
  129.         block_Release( p_block );
  130.         return NULL;
  131.     }
  132.     /* Date management */
  133.     if( p_block->i_pts > 0 || p_block->i_dts > 0 )
  134.     {
  135.         if( p_block->i_pts > 0 ) p_sys->i_pts = p_block->i_pts;
  136.         else if( p_block->i_dts > 0 ) p_sys->i_pts = p_block->i_dts;
  137.     }
  138.     i_video_header = *(uint32_t*)p_block->p_buffer; /* yes, it is native endian */
  139.     sbit = i_video_header >> 29; /* start bit position */
  140.     ebit = (i_video_header >> 26) & 7; /* end bit position */
  141.     msg_Dbg( p_dec, "sbit, ebit: %d,%d", sbit, ebit );
  142.     gob = (i_video_header >> 20) & 0xf; /* GOB number */
  143.     if( gob > 12 )
  144.     {
  145.         msg_Warn( p_dec, "invalid gob, buggy vic streamer?");
  146.     }
  147.     mba = (i_video_header >> 15) & 0x1f; /* Macroblock address predictor */
  148.     quant = (i_video_header >> 10) & 0x1f; /* quantizer */
  149.     mvdh = (i_video_header >> 5) & 0x1f; /* horizontal motion vector data */
  150.     mvdv = i_video_header & 0x1f; /* vertical motion vector data */
  151.     cc = p_block->i_buffer - 4;
  152.     msg_Dbg( p_dec, "packet size %d", cc );
  153.  
  154.     /* Find out p_vdec->i_raw_size */
  155.     p_sys->p_decoder->decode( p_block->p_buffer + 4 /*bp?*/,
  156.                               cc /*cc?*/,
  157.                               sbit /*sbit?*/,
  158.                               ebit /*ebit?*/,
  159.                               mba /* mba?*/,
  160.                               gob /* gob?*/,
  161.                               quant /* quant?*/,
  162.                               mvdh /* mvdh?*/,
  163.                               mvdv /* mvdv?*/ );
  164.     i_width = p_sys->p_decoder->width();
  165.     i_height = p_sys->p_decoder->height();
  166.     if( !p_sys->b_inited )
  167.     {
  168.         msg_Dbg( p_dec, "video size is perhaps %dx%d", i_width,
  169.                   i_height);
  170.         vout_InitFormat( &p_dec->fmt_out.video, VLC_FOURCC('I','4','2','0'),
  171.                          i_width, i_height,
  172.                          VOUT_ASPECT_FACTOR * i_width / i_height );
  173.         p_sys->b_inited = true;
  174.     }
  175.     p_pic = NULL;
  176.     p_sys->i_counter++;
  177. //    p_sys->p_decoder->sync();
  178.     if( p_block->i_flags & BLOCK_FLAG_END_OF_FRAME )
  179.     {
  180.         p_pic = decoder_NewPicture( p_dec );
  181.         if( !p_pic )
  182.         {
  183.             block_Release( p_block );
  184.             return NULL;
  185.         }
  186.         p_sys->p_decoder->sync();
  187.         p_sys->i_counter = 0;
  188.         p_frame = p_sys->p_decoder->frame();
  189.         vlc_memcpy( p_dec, p_pic->p[0].p_pixels, p_frame, i_width*i_height );
  190.         p_frame += i_width * i_height;
  191.         vlc_memcpy( p_dec, p_pic->p[1].p_pixels, p_frame, i_width*i_height/4 );
  192.         p_frame += i_width * i_height/4;
  193.         vlc_memcpy( p_dec, p_pic->p[2].p_pixels, p_frame, i_width*i_height/4 );
  194.         p_pic->date = p_sys->i_pts;
  195.     }
  196.     block_Release( p_block);
  197.     *pp_block = NULL;
  198.     return p_pic;
  199. //    return NULL;
  200. }