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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * theora.c: theora decoder module making use of libtheora.
  3.  *****************************************************************************
  4.  * Copyright (C) 1999-2001 the VideoLAN team
  5.  * $Id: 207a13f8251ebeeaf33290193268044988b352bd $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@videolan.org>
  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_sout.h>
  34. #include <vlc_input.h>
  35. #include <ogg/ogg.h>
  36. #include <theora/theora.h>
  37. /*****************************************************************************
  38.  * decoder_sys_t : theora decoder descriptor
  39.  *****************************************************************************/
  40. struct decoder_sys_t
  41. {
  42.     /* Module mode */
  43.     bool b_packetizer;
  44.     /*
  45.      * Input properties
  46.      */
  47.     int i_headers;
  48.     /*
  49.      * Theora properties
  50.      */
  51.     theora_info      ti;                        /* theora bitstream settings */
  52.     theora_comment   tc;                            /* theora comment header */
  53.     theora_state     td;                   /* theora bitstream user comments */
  54.     /*
  55.      * Decoding properties
  56.      */
  57.     bool b_decoded_first_keyframe;
  58.     /*
  59.      * Common properties
  60.      */
  61.     mtime_t i_pts;
  62. };
  63. /*****************************************************************************
  64.  * Local prototypes
  65.  *****************************************************************************/
  66. static int  OpenDecoder   ( vlc_object_t * );
  67. static int  OpenPacketizer( vlc_object_t * );
  68. static void CloseDecoder  ( vlc_object_t * );
  69. static void *DecodeBlock  ( decoder_t *, block_t ** );
  70. static int  ProcessHeaders( decoder_t * );
  71. static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** );
  72. static picture_t *DecodePacket( decoder_t *, ogg_packet * );
  73. static void ParseTheoraComments( decoder_t * );
  74. static void theora_CopyPicture( decoder_t *, picture_t *, yuv_buffer * );
  75. static int  OpenEncoder( vlc_object_t *p_this );
  76. static void CloseEncoder( vlc_object_t *p_this );
  77. static block_t *Encode( encoder_t *p_enc, picture_t *p_pict );
  78. /*****************************************************************************
  79.  * Module descriptor
  80.  *****************************************************************************/
  81. #define ENC_QUALITY_TEXT N_("Encoding quality")
  82. #define ENC_QUALITY_LONGTEXT N_( 
  83.   "Enforce a quality between 1 (low) and 10 (high), instead " 
  84.   "of specifying a particular bitrate. This will produce a VBR stream." )
  85. vlc_module_begin ()
  86.     set_category( CAT_INPUT )
  87.     set_subcategory( SUBCAT_INPUT_VCODEC )
  88.     set_shortname( "Theora" )
  89.     set_description( N_("Theora video decoder") )
  90.     set_capability( "decoder", 100 )
  91.     set_callbacks( OpenDecoder, CloseDecoder )
  92.     add_shortcut( "theora" )
  93.     add_submodule ()
  94.     set_description( N_("Theora video packetizer") )
  95.     set_capability( "packetizer", 100 )
  96.     set_callbacks( OpenPacketizer, CloseDecoder )
  97.     add_shortcut( "theora" )
  98.     add_submodule ()
  99.     set_description( N_("Theora video encoder") )
  100.     set_capability( "encoder", 150 )
  101.     set_callbacks( OpenEncoder, CloseEncoder )
  102.     add_shortcut( "theora" )
  103. #   define ENC_CFG_PREFIX "sout-theora-"
  104.     add_integer( ENC_CFG_PREFIX "quality", 2, NULL, ENC_QUALITY_TEXT,
  105.                  ENC_QUALITY_LONGTEXT, false )
  106. vlc_module_end ()
  107. static const char *const ppsz_enc_options[] = {
  108.     "quality", NULL
  109. };
  110. /*****************************************************************************
  111.  * OpenDecoder: probe the decoder and return score
  112.  *****************************************************************************/
  113. static int OpenDecoder( vlc_object_t *p_this )
  114. {
  115.     decoder_t *p_dec = (decoder_t*)p_this;
  116.     decoder_sys_t *p_sys;
  117.     if( p_dec->fmt_in.i_codec != VLC_FOURCC('t','h','e','o') )
  118.     {
  119.         return VLC_EGENERIC;
  120.     }
  121.     /* Allocate the memory needed to store the decoder's structure */
  122.     if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
  123.         return VLC_ENOMEM;
  124.     p_dec->p_sys->b_packetizer = false;
  125.     p_sys->i_pts = 0;
  126.     p_sys->b_decoded_first_keyframe = false;
  127.     /* Set output properties */
  128.     p_dec->fmt_out.i_cat = VIDEO_ES;
  129.     p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
  130.     /* Set callbacks */
  131.     p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
  132.         DecodeBlock;
  133.     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
  134.         DecodeBlock;
  135.     /* Init supporting Theora structures needed in header parsing */
  136.     theora_comment_init( &p_sys->tc );
  137.     theora_info_init( &p_sys->ti );
  138.     p_sys->i_headers = 0;
  139.     return VLC_SUCCESS;
  140. }
  141. static int OpenPacketizer( vlc_object_t *p_this )
  142. {
  143.     decoder_t *p_dec = (decoder_t*)p_this;
  144.     int i_ret = OpenDecoder( p_this );
  145.     if( i_ret == VLC_SUCCESS )
  146.     {
  147.         p_dec->p_sys->b_packetizer = true;
  148.         p_dec->fmt_out.i_codec = VLC_FOURCC( 't', 'h', 'e', 'o' );
  149.     }
  150.     return i_ret;
  151. }
  152. /****************************************************************************
  153.  * DecodeBlock: the whole thing
  154.  ****************************************************************************
  155.  * This function must be fed with ogg packets.
  156.  ****************************************************************************/
  157. static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
  158. {
  159.     decoder_sys_t *p_sys = p_dec->p_sys;
  160.     block_t *p_block;
  161.     ogg_packet oggpacket;
  162.     if( !pp_block || !*pp_block ) return NULL;
  163.     p_block = *pp_block;
  164.     /* Block to Ogg packet */
  165.     oggpacket.packet = p_block->p_buffer;
  166.     oggpacket.bytes = p_block->i_buffer;
  167.     oggpacket.granulepos = p_block->i_dts;
  168.     oggpacket.b_o_s = 0;
  169.     oggpacket.e_o_s = 0;
  170.     oggpacket.packetno = 0;
  171.     /* Check for headers */
  172.     if( p_sys->i_headers == 0 && p_dec->fmt_in.i_extra )
  173.     {
  174.         /* Headers already available as extra data */
  175.         p_sys->i_headers = 3;
  176.     }
  177.     else if( oggpacket.bytes && p_sys->i_headers < 3 )
  178.     {
  179.         /* Backup headers as extra data */
  180.         uint8_t *p_extra;
  181.         p_dec->fmt_in.p_extra =
  182.             realloc( p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra +
  183.                      oggpacket.bytes + 2 );
  184.         p_extra = ((uint8_t *)p_dec->fmt_in.p_extra) + p_dec->fmt_in.i_extra;
  185.         *(p_extra++) = oggpacket.bytes >> 8;
  186.         *(p_extra++) = oggpacket.bytes & 0xFF;
  187.         memcpy( p_extra, oggpacket.packet, oggpacket.bytes );
  188.         p_dec->fmt_in.i_extra += oggpacket.bytes + 2;
  189.         block_Release( *pp_block );
  190.         p_sys->i_headers++;
  191.         return NULL;
  192.     }
  193.     if( p_sys->i_headers == 3 )
  194.     {
  195.         if( ProcessHeaders( p_dec ) != VLC_SUCCESS )
  196.         {
  197.             p_sys->i_headers = 0;
  198.             p_dec->fmt_in.i_extra = 0;
  199.             block_Release( *pp_block );
  200.             return NULL;
  201.         }
  202.         else p_sys->i_headers++;
  203.     }
  204.     return ProcessPacket( p_dec, &oggpacket, pp_block );
  205. }
  206. /*****************************************************************************
  207.  * ProcessHeaders: process Theora headers.
  208.  *****************************************************************************/
  209. static int ProcessHeaders( decoder_t *p_dec )
  210. {
  211.     decoder_sys_t *p_sys = p_dec->p_sys;
  212.     ogg_packet oggpacket;
  213.     uint8_t *p_extra;
  214.     int i_extra;
  215.     if( !p_dec->fmt_in.i_extra ) return VLC_EGENERIC;
  216.     oggpacket.granulepos = -1;
  217.     oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
  218.     oggpacket.e_o_s = 0;
  219.     oggpacket.packetno = 0;
  220.     p_extra = p_dec->fmt_in.p_extra;
  221.     i_extra = p_dec->fmt_in.i_extra;
  222.     /* Take care of the initial Vorbis header */
  223.     oggpacket.bytes = *(p_extra++) << 8;
  224.     oggpacket.bytes |= (*(p_extra++) & 0xFF);
  225.     oggpacket.packet = p_extra;
  226.     p_extra += oggpacket.bytes;
  227.     i_extra -= (oggpacket.bytes + 2);
  228.     if( i_extra < 0 )
  229.     {
  230.         msg_Err( p_dec, "header data corrupted");
  231.         return VLC_EGENERIC;
  232.     }
  233.     if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
  234.     {
  235.         msg_Err( p_dec, "this bitstream does not contain Theora video data" );
  236.         return VLC_EGENERIC;
  237.     }
  238.     /* Set output properties */
  239.     switch( p_sys->ti.pixelformat )
  240.     {
  241.       case OC_PF_420:
  242.         p_dec->fmt_out.i_codec = VLC_FOURCC( 'I','4','2','0' );
  243.         break;
  244.       case OC_PF_422:
  245.         p_dec->fmt_out.i_codec = VLC_FOURCC( 'I','4','2','2' );
  246.         break;
  247.       case OC_PF_444:
  248.         p_dec->fmt_out.i_codec = VLC_FOURCC( 'I','4','4','4' );
  249.         break;
  250.       case OC_PF_RSVD:
  251.       default:
  252.         msg_Err( p_dec, "unknown chroma in theora sample" );
  253.         break;
  254.     }
  255.     p_dec->fmt_out.video.i_width = p_sys->ti.width;
  256.     p_dec->fmt_out.video.i_height = p_sys->ti.height;
  257.     if( p_sys->ti.frame_width && p_sys->ti.frame_height )
  258.     {
  259.         p_dec->fmt_out.video.i_visible_width = p_sys->ti.frame_width;
  260.         p_dec->fmt_out.video.i_visible_height = p_sys->ti.frame_height;
  261.         if( p_sys->ti.offset_x || p_sys->ti.offset_y )
  262.         {
  263.             p_dec->fmt_out.video.i_x_offset = p_sys->ti.offset_x;
  264.             p_dec->fmt_out.video.i_y_offset = p_sys->ti.offset_y;
  265.         }
  266.     }
  267.     if( p_sys->ti.aspect_denominator && p_sys->ti.aspect_numerator )
  268.     {
  269.         p_dec->fmt_out.video.i_aspect = ((int64_t)VOUT_ASPECT_FACTOR) *
  270.             ( p_sys->ti.aspect_numerator * p_dec->fmt_out.video.i_width ) /
  271.             ( p_sys->ti.aspect_denominator * p_dec->fmt_out.video.i_height );
  272.     }
  273.     else
  274.     {
  275.         p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *
  276.             p_sys->ti.frame_width / p_sys->ti.frame_height;
  277.     }
  278.     if( p_sys->ti.fps_numerator > 0 && p_sys->ti.fps_denominator > 0 )
  279.     {
  280.         p_dec->fmt_out.video.i_frame_rate = p_sys->ti.fps_numerator;
  281.         p_dec->fmt_out.video.i_frame_rate_base = p_sys->ti.fps_denominator;
  282.     }
  283.     msg_Dbg( p_dec, "%dx%d %.02f fps video, frame content "
  284.              "is %dx%d with offset (%d,%d)",
  285.              p_sys->ti.width, p_sys->ti.height,
  286.              (double)p_sys->ti.fps_numerator/p_sys->ti.fps_denominator,
  287.              p_sys->ti.frame_width, p_sys->ti.frame_height,
  288.              p_sys->ti.offset_x, p_sys->ti.offset_y );
  289.     /* Sanity check that seems necessary for some corrupted files */
  290.     if( p_sys->ti.width < p_sys->ti.frame_width ||
  291.         p_sys->ti.height < p_sys->ti.frame_height )
  292.     {
  293.         msg_Warn( p_dec, "trying to correct invalid theora header "
  294.                   "(frame size (%dx%d) is smaller than frame content (%d,%d))",
  295.                   p_sys->ti.width, p_sys->ti.height,
  296.                   p_sys->ti.frame_width, p_sys->ti.frame_height );
  297.         if( p_sys->ti.width < p_sys->ti.frame_width )
  298.             p_sys->ti.width = p_sys->ti.frame_width;
  299.         if( p_sys->ti.height < p_sys->ti.frame_height )
  300.             p_sys->ti.height = p_sys->ti.frame_height;
  301.     }
  302.     /* The next packet in order is the comments header */
  303.     oggpacket.b_o_s = 0;
  304.     oggpacket.bytes = *(p_extra++) << 8;
  305.     oggpacket.bytes |= (*(p_extra++) & 0xFF);
  306.     oggpacket.packet = p_extra;
  307.     p_extra += oggpacket.bytes;
  308.     i_extra -= (oggpacket.bytes + 2);
  309.     if( i_extra < 0 )
  310.     {
  311.         msg_Err( p_dec, "header data corrupted");
  312.         return VLC_EGENERIC;
  313.     }
  314.     /* The next packet in order is the comments header */
  315.     if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
  316.     {
  317.         msg_Err( p_dec, "2nd Theora header is corrupted" );
  318.         return VLC_EGENERIC;
  319.     }
  320.     ParseTheoraComments( p_dec );
  321.     /* The next packet in order is the codebooks header
  322.      * We need to watch out that this packet is not missing as a
  323.      * missing or corrupted header is fatal. */
  324.     oggpacket.bytes = *(p_extra++) << 8;
  325.     oggpacket.bytes |= (*(p_extra++) & 0xFF);
  326.     oggpacket.packet = p_extra;
  327.     i_extra -= (oggpacket.bytes + 2);
  328.     if( i_extra < 0 )
  329.     {
  330.         msg_Err( p_dec, "header data corrupted");
  331.         return VLC_EGENERIC;
  332.     }
  333.     /* The next packet in order is the codebooks header
  334.      * We need to watch out that this packet is not missing as a
  335.      * missing or corrupted header is fatal */
  336.     if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 )
  337.     {
  338.         msg_Err( p_dec, "3rd Theora header is corrupted" );
  339.         return VLC_EGENERIC;
  340.     }
  341.     if( !p_sys->b_packetizer )
  342.     {
  343.         /* We have all the headers, initialize decoder */
  344.         theora_decode_init( &p_sys->td, &p_sys->ti );
  345.     }
  346.     else
  347.     {
  348.         p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
  349.         p_dec->fmt_out.p_extra =
  350.             realloc( p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );
  351.         memcpy( p_dec->fmt_out.p_extra,
  352.                 p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
  353.     }
  354.     return VLC_SUCCESS;
  355. }
  356. /*****************************************************************************
  357.  * ProcessPacket: processes a theora packet.
  358.  *****************************************************************************/
  359. static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
  360.                             block_t **pp_block )
  361. {
  362.     decoder_sys_t *p_sys = p_dec->p_sys;
  363.     block_t *p_block = *pp_block;
  364.     void *p_buf;
  365.     if( ( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) != 0 )
  366.     {
  367.         /* Don't send the the first packet after a discontinuity to
  368.          * theora_decode, otherwise we get purple/green display artifacts
  369.          * appearing in the video output */
  370.         return NULL;
  371.     }
  372.     /* Date management */
  373.     if( p_block->i_pts > 0 && p_block->i_pts != p_sys->i_pts )
  374.     {
  375.         p_sys->i_pts = p_block->i_pts;
  376.     }
  377.     *pp_block = NULL; /* To avoid being fed the same packet again */
  378.     if( p_sys->b_packetizer )
  379.     {
  380.         /* Date management */
  381.         p_block->i_dts = p_block->i_pts = p_sys->i_pts;
  382.         if( p_sys->i_headers >= 3 )
  383.             p_block->i_length = p_sys->i_pts - p_block->i_pts;
  384.         else
  385.             p_block->i_length = 0;
  386.         p_buf = p_block;
  387.     }
  388.     else
  389.     {
  390.         if( p_sys->i_headers >= 3 )
  391.             p_buf = DecodePacket( p_dec, p_oggpacket );
  392.         else
  393.             p_buf = NULL;
  394.         if( p_block ) block_Release( p_block );
  395.     }
  396.     /* Date management */
  397.     p_sys->i_pts += ( INT64_C(1000000) * p_sys->ti.fps_denominator /
  398.                       p_sys->ti.fps_numerator ); /* 1 frame per packet */
  399.     return p_buf;
  400. }
  401. /*****************************************************************************
  402.  * DecodePacket: decodes a Theora packet.
  403.  *****************************************************************************/
  404. static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
  405. {
  406.     decoder_sys_t *p_sys = p_dec->p_sys;
  407.     picture_t *p_pic;
  408.     yuv_buffer yuv;
  409.     theora_decode_packetin( &p_sys->td, p_oggpacket );
  410.     /* Check for keyframe */
  411.     if( !(p_oggpacket->packet[0] & 0x80) /* data packet */ &&
  412.         !(p_oggpacket->packet[0] & 0x40) /* intra frame */ )
  413.         p_sys->b_decoded_first_keyframe = true;
  414.     /* If we haven't seen a single keyframe yet, don't let Theora decode
  415.      * anything, otherwise we'll get display artifacts.  (This is impossible
  416.      * in the general case, but can happen if e.g. we play a network stream
  417.      * using a timed URL, such that the server doesn't start the video with a
  418.      * keyframe). */
  419.     if( p_sys->b_decoded_first_keyframe )
  420.         theora_decode_YUVout( &p_sys->td, &yuv );
  421.     else
  422.         return NULL;
  423.     /* Get a new picture */
  424.     p_pic = decoder_NewPicture( p_dec );
  425.     if( !p_pic ) return NULL;
  426.     theora_CopyPicture( p_dec, p_pic, &yuv );
  427.     p_pic->date = p_sys->i_pts;
  428.     return p_pic;
  429. }
  430. /*****************************************************************************
  431.  * ParseTheoraComments:
  432.  *****************************************************************************/
  433. static void ParseTheoraComments( decoder_t *p_dec )
  434. {
  435.     char *psz_name, *psz_value, *psz_comment;
  436.     int i = 0;
  437.     while ( i < p_dec->p_sys->tc.comments )
  438.     {
  439.         psz_comment = strdup( p_dec->p_sys->tc.user_comments[i] );
  440.         if( !psz_comment )
  441.             break;
  442.         psz_name = psz_comment;
  443.         psz_value = strchr( psz_comment, '=' );
  444.         if( psz_value )
  445.         {
  446.             *psz_value = '';
  447.             psz_value++;
  448.             if( !p_dec->p_description )
  449.                 p_dec->p_description = vlc_meta_New();
  450.             if( p_dec->p_description )
  451.                 vlc_meta_AddExtra( p_dec->p_description, psz_name, psz_value );
  452.         }
  453.         free( psz_comment );
  454.         i++;
  455.     }
  456. }
  457. /*****************************************************************************
  458.  * CloseDecoder: theora decoder destruction
  459.  *****************************************************************************/
  460. static void CloseDecoder( vlc_object_t *p_this )
  461. {
  462.     decoder_t *p_dec = (decoder_t *)p_this;
  463.     decoder_sys_t *p_sys = p_dec->p_sys;
  464.     theora_info_clear( &p_sys->ti );
  465.     theora_comment_clear( &p_sys->tc );
  466.     free( p_sys );
  467. }
  468. /*****************************************************************************
  469.  * theora_CopyPicture: copy a picture from theora internal buffers to a
  470.  *                     picture_t structure.
  471.  *****************************************************************************/
  472. static void theora_CopyPicture( decoder_t *p_dec, picture_t *p_pic,
  473.                                 yuv_buffer *yuv )
  474. {
  475.     int i_plane, i_line, i_dst_stride, i_src_stride;
  476.     uint8_t *p_dst, *p_src;
  477.     for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
  478.     {
  479.         p_dst = p_pic->p[i_plane].p_pixels;
  480.         p_src = i_plane ? (i_plane - 1 ? yuv->v : yuv->u ) : yuv->y;
  481.         i_dst_stride  = p_pic->p[i_plane].i_pitch;
  482.         i_src_stride  = i_plane ? yuv->uv_stride : yuv->y_stride;
  483.         for( i_line = 0; i_line < p_pic->p[i_plane].i_lines; i_line++ )
  484.         {
  485.             vlc_memcpy( p_dst, p_src,
  486.                         i_plane ? yuv->uv_width : yuv->y_width );
  487.             p_src += i_src_stride;
  488.             p_dst += i_dst_stride;
  489.         }
  490.     }
  491. }
  492. /*****************************************************************************
  493.  * encoder_sys_t : theora encoder descriptor
  494.  *****************************************************************************/
  495. struct encoder_sys_t
  496. {
  497.     /*
  498.      * Input properties
  499.      */
  500.     bool b_headers;
  501.     /*
  502.      * Theora properties
  503.      */
  504.     theora_info      ti;                        /* theora bitstream settings */
  505.     theora_comment   tc;                            /* theora comment header */
  506.     theora_state     td;                   /* theora bitstream user comments */
  507.     int i_width, i_height;
  508. };
  509. /*****************************************************************************
  510.  * OpenEncoder: probe the encoder and return score
  511.  *****************************************************************************/
  512. static int OpenEncoder( vlc_object_t *p_this )
  513. {
  514.     encoder_t *p_enc = (encoder_t *)p_this;
  515.     encoder_sys_t *p_sys = p_enc->p_sys;
  516.     ogg_packet header;
  517.     uint8_t *p_extra;
  518.     vlc_value_t val;
  519.     int i_quality, i;
  520.     if( p_enc->fmt_out.i_codec != VLC_FOURCC('t','h','e','o') &&
  521.         !p_enc->b_force )
  522.     {
  523.         return VLC_EGENERIC;
  524.     }
  525.     /* Allocate the memory needed to store the decoder's structure */
  526.     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
  527.         return VLC_ENOMEM;
  528.     p_enc->p_sys = p_sys;
  529.     p_enc->pf_encode_video = Encode;
  530.     p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
  531.     p_enc->fmt_out.i_codec = VLC_FOURCC('t','h','e','o');
  532.     config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
  533.     var_Get( p_enc, ENC_CFG_PREFIX "quality", &val );
  534.     i_quality = val.i_int;
  535.     if( i_quality > 10 ) i_quality = 10;
  536.     if( i_quality < 0 ) i_quality = 0;
  537.     theora_info_init( &p_sys->ti );
  538.     p_sys->ti.width = p_enc->fmt_in.video.i_width;
  539.     p_sys->ti.height = p_enc->fmt_in.video.i_height;
  540.     if( p_sys->ti.width % 16 || p_sys->ti.height % 16 )
  541.     {
  542.         /* Pictures from the transcoder should always have a pitch
  543.          * which is a multiple of 16 */
  544.         p_sys->ti.width = (p_sys->ti.width + 15) >> 4 << 4;
  545.         p_sys->ti.height = (p_sys->ti.height + 15) >> 4 << 4;
  546.         msg_Dbg( p_enc, "padding video from %dx%d to %dx%d",
  547.                  p_enc->fmt_in.video.i_width, p_enc->fmt_in.video.i_height,
  548.                  p_sys->ti.width, p_sys->ti.height );
  549.     }
  550.     p_sys->ti.frame_width = p_enc->fmt_in.video.i_width;
  551.     p_sys->ti.frame_height = p_enc->fmt_in.video.i_height;
  552.     p_sys->ti.offset_x = 0 /*frame_x_offset*/;
  553.     p_sys->ti.offset_y = 0 /*frame_y_offset*/;
  554.     p_sys->i_width = p_sys->ti.width;
  555.     p_sys->i_height = p_sys->ti.height;
  556.     if( !p_enc->fmt_in.video.i_frame_rate ||
  557.         !p_enc->fmt_in.video.i_frame_rate_base )
  558.     {
  559.         p_sys->ti.fps_numerator = 25;
  560.         p_sys->ti.fps_denominator = 1;
  561.     }
  562.     else
  563.     {
  564.         p_sys->ti.fps_numerator = p_enc->fmt_in.video.i_frame_rate;
  565.         p_sys->ti.fps_denominator = p_enc->fmt_in.video.i_frame_rate_base;
  566.     }
  567.     if( p_enc->fmt_in.video.i_aspect )
  568.     {
  569.         uint64_t i_num, i_den;
  570.         unsigned i_dst_num, i_dst_den;
  571.         i_num = p_enc->fmt_in.video.i_aspect * (int64_t)p_sys->ti.height;
  572.         i_den = VOUT_ASPECT_FACTOR * p_sys->ti.width;
  573.         vlc_ureduce( &i_dst_num, &i_dst_den, i_num, i_den, 0 );
  574.         p_sys->ti.aspect_numerator = i_dst_num;
  575.         p_sys->ti.aspect_denominator = i_dst_den;
  576.     }
  577.     else
  578.     {
  579.         p_sys->ti.aspect_numerator = 4;
  580.         p_sys->ti.aspect_denominator = 3;
  581.     }
  582.     p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
  583.     p_sys->ti.quality = ((float)i_quality) * 6.3;
  584.     p_sys->ti.dropframes_p = 0;
  585.     p_sys->ti.quick_p = 1;
  586.     p_sys->ti.keyframe_auto_p = 1;
  587.     p_sys->ti.keyframe_frequency = 64;
  588.     p_sys->ti.keyframe_frequency_force = 64;
  589.     p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
  590.     p_sys->ti.keyframe_auto_threshold = 80;
  591.     p_sys->ti.keyframe_mindistance = 8;
  592.     p_sys->ti.noise_sensitivity = 1;
  593.     theora_encode_init( &p_sys->td, &p_sys->ti );
  594.     theora_comment_init( &p_sys->tc );
  595.     /* Create and store headers */
  596.     p_enc->fmt_out.i_extra = 3 * 2;
  597.     for( i = 0; i < 3; i++ )
  598.     {
  599.         if( i == 0 ) theora_encode_header( &p_sys->td, &header );
  600.         else if( i == 1 ) theora_encode_comment( &p_sys->tc, &header );
  601.         else if( i == 2 ) theora_encode_tables( &p_sys->td, &header );
  602.         p_enc->fmt_out.p_extra =
  603.             realloc( p_enc->fmt_out.p_extra,
  604.                      p_enc->fmt_out.i_extra + header.bytes );
  605.         p_extra = p_enc->fmt_out.p_extra;
  606.         p_extra += p_enc->fmt_out.i_extra + (i-3)*2;
  607.         p_enc->fmt_out.i_extra += header.bytes;
  608.         *(p_extra++) = header.bytes >> 8;
  609.         *(p_extra++) = header.bytes & 0xFF;
  610.         memcpy( p_extra, header.packet, header.bytes );
  611.     }
  612.     return VLC_SUCCESS;
  613. }
  614. /****************************************************************************
  615.  * Encode: the whole thing
  616.  ****************************************************************************
  617.  * This function spits out ogg packets.
  618.  ****************************************************************************/
  619. static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
  620. {
  621.     encoder_sys_t *p_sys = p_enc->p_sys;
  622.     ogg_packet oggpacket;
  623.     block_t *p_block;
  624.     yuv_buffer yuv;
  625.     int i;
  626.     /* Sanity check */
  627.     if( p_pict->p[0].i_pitch < (int)p_sys->i_width ||
  628.         p_pict->p[0].i_lines < (int)p_sys->i_height )
  629.     {
  630.         msg_Warn( p_enc, "frame is smaller than encoding size"
  631.                   "(%ix%i->%ix%i) -> dropping frame",
  632.                   p_pict->p[0].i_pitch, p_pict->p[0].i_lines,
  633.                   p_sys->i_width, p_sys->i_height );
  634.         return NULL;
  635.     }
  636.     /* Fill padding */
  637.     if( p_pict->p[0].i_visible_pitch < (int)p_sys->i_width )
  638.     {
  639.         for( i = 0; i < p_sys->i_height; i++ )
  640.         {
  641.             memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
  642.                     p_pict->p[0].i_visible_pitch,
  643.                     *( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
  644.                        p_pict->p[0].i_visible_pitch - 1 ),
  645.                     p_sys->i_width - p_pict->p[0].i_visible_pitch );
  646.         }
  647.         for( i = 0; i < p_sys->i_height / 2; i++ )
  648.         {
  649.             memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
  650.                     p_pict->p[1].i_visible_pitch,
  651.                     *( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
  652.                        p_pict->p[1].i_visible_pitch - 1 ),
  653.                     p_sys->i_width / 2 - p_pict->p[1].i_visible_pitch );
  654.             memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
  655.                     p_pict->p[2].i_visible_pitch,
  656.                     *( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
  657.                        p_pict->p[2].i_visible_pitch - 1 ),
  658.                     p_sys->i_width / 2 - p_pict->p[2].i_visible_pitch );
  659.         }
  660.     }
  661.     if( p_pict->p[0].i_visible_lines < (int)p_sys->i_height )
  662.     {
  663.         for( i = p_pict->p[0].i_visible_lines; i < p_sys->i_height; i++ )
  664.         {
  665.             memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch, 0,
  666.                     p_sys->i_width );
  667.         }
  668.         for( i = p_pict->p[1].i_visible_lines; i < p_sys->i_height / 2; i++ )
  669.         {
  670.             memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch, 0x80,
  671.                     p_sys->i_width / 2 );
  672.             memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch, 0x80,
  673.                     p_sys->i_width / 2 );
  674.         }
  675.     }
  676.     /* Theora is a one-frame-in, one-frame-out system. Submit a frame
  677.      * for compression and pull out the packet. */
  678.     yuv.y_width  = p_sys->i_width;
  679.     yuv.y_height = p_sys->i_height;
  680.     yuv.y_stride = p_pict->p[0].i_pitch;
  681.     yuv.uv_width  = p_sys->i_width / 2;
  682.     yuv.uv_height = p_sys->i_height / 2;
  683.     yuv.uv_stride = p_pict->p[1].i_pitch;
  684.     yuv.y = p_pict->p[0].p_pixels;
  685.     yuv.u = p_pict->p[1].p_pixels;
  686.     yuv.v = p_pict->p[2].p_pixels;
  687.     if( theora_encode_YUVin( &p_sys->td, &yuv ) < 0 )
  688.     {
  689.         msg_Warn( p_enc, "failed encoding a frame" );
  690.         return NULL;
  691.     }
  692.     theora_encode_packetout( &p_sys->td, 0, &oggpacket );
  693.     /* Ogg packet to block */
  694.     p_block = block_New( p_enc, oggpacket.bytes );
  695.     memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
  696.     p_block->i_dts = p_block->i_pts = p_pict->date;
  697.     if( theora_packet_iskeyframe( &oggpacket ) )
  698.     {
  699.         p_block->i_flags |= BLOCK_FLAG_TYPE_I;
  700.     }
  701.     return p_block;
  702. }
  703. /*****************************************************************************
  704.  * CloseEncoder: theora encoder destruction
  705.  *****************************************************************************/
  706. static void CloseEncoder( vlc_object_t *p_this )
  707. {
  708.     encoder_t *p_enc = (encoder_t *)p_this;
  709.     encoder_sys_t *p_sys = p_enc->p_sys;
  710.     theora_info_clear( &p_sys->ti );
  711.     theora_comment_clear( &p_sys->tc );
  712.     free( p_sys );
  713. }