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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * schroedinger.c: Dirac decoder module making use of libschroedinger.
  3.  *          (http://www.bbc.co.uk/rd/projects/dirac/index.shtml)
  4.  *          (http://diracvideo.org)
  5.  *****************************************************************************
  6.  * Copyright (C) 2008 the VideoLAN team
  7.  * $Id: 8b7abb5f3711be814299f83a35d2c45638df8f0f $
  8.  *
  9.  * Authors: Jonathan Rosser <jonathan.rosser@gmail.com>
  10.  *          David Flynn <davidf at rd dot bbc.co.uk>
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  25.  *****************************************************************************/
  26. /*****************************************************************************
  27.  * Preamble
  28.  *****************************************************************************/
  29. #ifdef HAVE_CONFIG_H
  30. # include "config.h"
  31. #endif
  32. #include <vlc_common.h>
  33. #include <vlc_plugin.h>
  34. #include <vlc_codec.h>
  35. #include <vlc_sout.h>
  36. #include <vlc_vout.h>
  37. #include <schroedinger/schro.h>
  38. /*****************************************************************************
  39.  * Module descriptor
  40.  *****************************************************************************/
  41. static int        OpenDecoder  ( vlc_object_t * );
  42. static void       CloseDecoder ( vlc_object_t * );
  43. vlc_module_begin ()
  44.     set_category( CAT_INPUT )
  45.     set_subcategory( SUBCAT_INPUT_VCODEC )
  46.     set_description( N_("Schroedinger video decoder") )
  47.     set_capability( "decoder", 200 )
  48.     set_callbacks( OpenDecoder, CloseDecoder )
  49.     add_shortcut( "schroedinger" )
  50. vlc_module_end ()
  51. /*****************************************************************************
  52.  * Local prototypes
  53.  *****************************************************************************/
  54. static picture_t *DecodeBlock  ( decoder_t *p_dec, block_t **pp_block );
  55. struct picture_free_t
  56. {
  57.    picture_t *p_pic;
  58.    decoder_t *p_dec;
  59. };
  60. /*****************************************************************************
  61.  * decoder_sys_t : Schroedinger decoder descriptor
  62.  *****************************************************************************/
  63. struct decoder_sys_t
  64. {
  65.     /*
  66.      * Dirac properties
  67.      */
  68.     mtime_t i_lastpts;
  69.     mtime_t i_frame_pts_delta;
  70.     SchroDecoder *p_schro;
  71.     SchroVideoFormat *p_format;
  72. };
  73. /*****************************************************************************
  74.  * OpenDecoder: probe the decoder and return score
  75.  *****************************************************************************/
  76. static int OpenDecoder( vlc_object_t *p_this )
  77. {
  78.     decoder_t *p_dec = (decoder_t*)p_this;
  79.     decoder_sys_t *p_sys;
  80.     SchroDecoder *p_schro;
  81.     if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','r','a','c') )
  82.     {
  83.         return VLC_EGENERIC;
  84.     }
  85.     /* Allocate the memory needed to store the decoder's structure */
  86.     p_sys = malloc(sizeof(decoder_sys_t));
  87.     if( p_sys == NULL )
  88.         return VLC_ENOMEM;
  89.     /* Initialise the schroedinger (and hence liboil libraries */
  90.     /* This does no allocation and is safe to call */
  91.     schro_init();
  92.     /* Initialise the schroedinger decoder */
  93.     if( !(p_schro = schro_decoder_new()) )
  94.     {
  95.         free( p_sys );
  96.         return VLC_EGENERIC;
  97.     }
  98.     p_dec->p_sys = p_sys;
  99.     p_sys->p_schro = p_schro;
  100.     p_sys->p_format = NULL;
  101.     p_sys->i_lastpts = -1;
  102.     p_sys->i_frame_pts_delta = 0;
  103.     /* Set output properties */
  104.     p_dec->fmt_out.i_cat = VIDEO_ES;
  105.     p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
  106.     /* Set callbacks */
  107.     p_dec->pf_decode_video = DecodeBlock;
  108.     return VLC_SUCCESS;
  109. }
  110. /*****************************************************************************
  111.  * SetPictureFormat: Set the decoded picture params to the ones from the stream
  112.  *****************************************************************************/
  113. static void SetVideoFormat( decoder_t *p_dec )
  114. {
  115.     decoder_sys_t *p_sys = p_dec->p_sys;
  116.     double f_aspect;
  117.     p_sys->p_format = schro_decoder_get_video_format(p_sys->p_schro);
  118.     if( p_sys->p_format == NULL ) return;
  119.     p_sys->i_frame_pts_delta = INT64_C(1000000)
  120.                             * p_sys->p_format->frame_rate_denominator
  121.                             / p_sys->p_format->frame_rate_numerator;
  122.     switch( p_sys->p_format->chroma_format )
  123.     {
  124.     case SCHRO_CHROMA_420: p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0'); break;
  125.     case SCHRO_CHROMA_422: p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','2'); break;
  126.     case SCHRO_CHROMA_444: p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','4','4'); break;
  127.     default:
  128.         p_dec->fmt_out.i_codec = 0;
  129.         break;
  130.     }
  131.     p_dec->fmt_out.video.i_visible_width = p_sys->p_format->clean_width;
  132.     p_dec->fmt_out.video.i_x_offset = p_sys->p_format->left_offset;
  133.     p_dec->fmt_out.video.i_width = p_sys->p_format->width;
  134.     p_dec->fmt_out.video.i_visible_height = p_sys->p_format->clean_height;
  135.     p_dec->fmt_out.video.i_y_offset = p_sys->p_format->top_offset;
  136.     p_dec->fmt_out.video.i_height = p_sys->p_format->height;
  137.     /* aspect_ratio_[numerator|denominator] describes the pixel aspect ratio */
  138.     f_aspect = (double)
  139.         ( p_sys->p_format->aspect_ratio_numerator * p_sys->p_format->width ) /
  140.         ( p_sys->p_format->aspect_ratio_denominator * p_sys->p_format->height);
  141.     p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * f_aspect;
  142.     p_dec->fmt_out.video.i_frame_rate =
  143.         p_sys->p_format->frame_rate_numerator;
  144.     p_dec->fmt_out.video.i_frame_rate_base =
  145.         p_sys->p_format->frame_rate_denominator;
  146. }
  147. /*****************************************************************************
  148.  * SchroFrameFree: schro_frame callback to release the associated picture_t
  149.  * When schro_decoder_reset() is called there will be pictures in the
  150.  * decoding pipeline that need to be released rather than displayed.
  151.  *****************************************************************************/
  152. static void SchroFrameFree( SchroFrame *frame, void *priv)
  153. {
  154.     struct picture_free_t *p_free = priv;
  155.     if( !p_free )
  156.         return;
  157.     decoder_DeletePicture( p_free->p_dec, p_free->p_pic );
  158.     free(p_free);
  159.     (void)frame;
  160. }
  161. /*****************************************************************************
  162.  * CreateSchroFrameFromPic: wrap a picture_t in a SchroFrame
  163.  *****************************************************************************/
  164. static SchroFrame *CreateSchroFrameFromPic( decoder_t *p_dec )
  165. {
  166.     decoder_sys_t *p_sys = p_dec->p_sys;
  167.     SchroFrame *p_schroframe = schro_frame_new();
  168.     picture_t *p_pic = NULL;
  169.     struct picture_free_t *p_free;
  170.     if( !p_schroframe )
  171.         return NULL;
  172.     p_pic = decoder_NewPicture( p_dec );
  173.     if( !p_pic )
  174.         return NULL;
  175.     p_schroframe->format = SCHRO_FRAME_FORMAT_U8_420;
  176.     if( p_sys->p_format->chroma_format == SCHRO_CHROMA_422 )
  177.     {
  178.         p_schroframe->format = SCHRO_FRAME_FORMAT_U8_422;
  179.     }
  180.     else if( p_sys->p_format->chroma_format == SCHRO_CHROMA_444 )
  181.     {
  182.         p_schroframe->format = SCHRO_FRAME_FORMAT_U8_444;
  183.     }
  184.     p_schroframe->width = p_sys->p_format->width;
  185.     p_schroframe->height = p_sys->p_format->height;
  186.     p_free = malloc( sizeof( *p_free ) );
  187.     p_free->p_pic = p_pic;
  188.     p_free->p_dec = p_dec;
  189.     schro_frame_set_free_callback( p_schroframe, SchroFrameFree, p_free );
  190.     for( int i=0; i<3; i++ )
  191.     {
  192.         p_schroframe->components[i].width = p_pic->p[i].i_visible_pitch;
  193.         p_schroframe->components[i].stride = p_pic->p[i].i_pitch;
  194.         p_schroframe->components[i].height = p_pic->p[i].i_visible_lines;
  195.         p_schroframe->components[i].length =
  196.             p_pic->p[i].i_pitch * p_pic->p[i].i_lines;
  197.         p_schroframe->components[i].data = p_pic->p[i].p_pixels;
  198.         if(i!=0)
  199.         {
  200.             p_schroframe->components[i].v_shift =
  201.                 SCHRO_FRAME_FORMAT_V_SHIFT( p_schroframe->format );
  202.             p_schroframe->components[i].h_shift =
  203.                 SCHRO_FRAME_FORMAT_H_SHIFT( p_schroframe->format );
  204.         }
  205.     }
  206.     p_pic->b_progressive = !p_sys->p_format->interlaced;
  207.     p_pic->b_top_field_first = p_sys->p_format->top_field_first;
  208.     p_pic->i_nb_fields = 2;
  209.     return p_schroframe;
  210. }
  211. /*****************************************************************************
  212.  * SchroBufferFree: schro_buffer callback to release the associated block_t
  213.  *****************************************************************************/
  214. static void SchroBufferFree( SchroBuffer *buf, void *priv )
  215. {
  216.     block_t *p_block = priv;
  217.     if( !p_block )
  218.         return;
  219.     block_Release( p_block );
  220.     (void)buf;
  221. }
  222. /*****************************************************************************
  223.  * CloseDecoder: decoder destruction
  224.  *****************************************************************************/
  225. static void CloseDecoder( vlc_object_t *p_this )
  226. {
  227.     decoder_t *p_dec = (decoder_t *)p_this;
  228.     decoder_sys_t *p_sys = p_dec->p_sys;
  229.     schro_decoder_free( p_sys->p_schro );
  230.     free( p_sys );
  231. }
  232. /****************************************************************************
  233.  * DecodeBlock: the whole thing
  234.  ****************************************************************************
  235.  * Blocks need not be Dirac dataunit aligned.
  236.  * If a block has a PTS signaled, it applies to the first picture at or after p_block
  237.  *
  238.  * If this function returns a picture (!NULL), it is called again and the
  239.  * same block is resubmitted.  To avoid this, set *pp_block to NULL;
  240.  * If this function returns NULL, the *pp_block is lost (and leaked).
  241.  * This function must free all blocks when finished with them.
  242.  ****************************************************************************/
  243. static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
  244. {
  245.     decoder_sys_t *p_sys = p_dec->p_sys;
  246.     if( !pp_block ) return NULL;
  247.     if ( *pp_block ) {
  248.         block_t *p_block = *pp_block;
  249.         /* reset the decoder when seeking as the decode in progress is invalid */
  250.         /* discard the block as it is just a null magic block */
  251.         if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY ) {
  252.             schro_decoder_reset( p_sys->p_schro );
  253.             p_sys->i_lastpts = -1;
  254.             block_Release( p_block );
  255.             *pp_block = NULL;
  256.             return NULL;
  257.         }
  258.         SchroBuffer *p_schrobuffer;
  259.         p_schrobuffer = schro_buffer_new_with_data( p_block->p_buffer, p_block->i_buffer );
  260.         p_schrobuffer->free = SchroBufferFree;
  261.         p_schrobuffer->priv = p_block;
  262.         if( p_block->i_pts != VLC_TS_INVALID ) {
  263.             mtime_t *p_pts = malloc( sizeof(*p_pts) );
  264.             if( p_pts ) {
  265.                 *p_pts = p_block->i_pts;
  266.                 /* if this call fails, p_pts is freed automatically */
  267.                 p_schrobuffer->tag = schro_tag_new( p_pts, free );
  268.             }
  269.         }
  270.         /* this stops the same block being fed back into this function if
  271.          * we were on the next iteration of this loop to output a picture */
  272.         *pp_block = NULL;
  273.         schro_decoder_autoparse_push( p_sys->p_schro, p_schrobuffer );
  274.         /* DO NOT refer to p_block after this point, it may have been freed */
  275.     }
  276.     while( 1 )
  277.     {
  278.         SchroFrame *p_schroframe;
  279.         picture_t *p_pic;
  280.         int state = schro_decoder_autoparse_wait( p_sys->p_schro );
  281.         switch( state )
  282.         {
  283.         case SCHRO_DECODER_FIRST_ACCESS_UNIT:
  284.             SetVideoFormat( p_dec );
  285.             break;
  286.         case SCHRO_DECODER_NEED_BITS:
  287.             return NULL;
  288.         case SCHRO_DECODER_NEED_FRAME:
  289.             p_schroframe = CreateSchroFrameFromPic( p_dec );
  290.             if( !p_schroframe )
  291.             {
  292.                 msg_Err( p_dec, "Could not allocate picture for decoder");
  293.                 return NULL;
  294.             }
  295.             schro_decoder_add_output_picture( p_sys->p_schro, p_schroframe);
  296.             break;
  297.         case SCHRO_DECODER_OK: {
  298.             SchroTag *p_tag = schro_decoder_get_picture_tag( p_sys->p_schro );
  299.             p_schroframe = schro_decoder_pull( p_sys->p_schro );
  300.             if( !p_schroframe || !p_schroframe->priv )
  301.             {
  302.                 /* frame can't be one that was allocated by us
  303.                  *   -- no private data: discard */
  304.                 if( p_tag ) schro_tag_free( p_tag );
  305.                 if( p_schroframe ) schro_frame_unref( p_schroframe );
  306.                 break;
  307.             }
  308.             p_pic = ((struct picture_free_t*) p_schroframe->priv)->p_pic;
  309.             p_schroframe->priv = NULL;
  310.             if( p_tag )
  311.             {
  312.                 /* free is handled by schro_frame_unref */
  313.                 p_pic->date = *(mtime_t*) p_tag->value;
  314.                 schro_tag_free( p_tag );
  315.             }
  316.             else if( p_sys->i_lastpts >= 0 )
  317.             {
  318.                 /* NB, this shouldn't happen since the packetizer does a
  319.                  * very thorough job of inventing timestamps.  The
  320.                  * following is just a very rough fall back incase packetizer
  321.                  * is missing. */
  322.                 /* maybe it would be better to set p_pic->b_force ? */
  323.                 p_pic->date = p_sys->i_lastpts + p_sys->i_frame_pts_delta;
  324.             }
  325.             p_sys->i_lastpts = p_pic->date;
  326.             schro_frame_unref( p_schroframe );
  327.             return p_pic;
  328.         }
  329.         case SCHRO_DECODER_EOS:
  330.             /* NB, the new api will not emit _EOS, it handles the reset internally */
  331.             break;
  332.         case SCHRO_DECODER_ERROR:
  333.             msg_Err( p_dec, "SCHRO_DECODER_ERROR");
  334.             return NULL;
  335.         }
  336.     }
  337. }