Changeset 3420


Ignore:
Timestamp:
Feb 24, 2011 7:47:55 AM (13 years ago)
Author:
nanang
Message:

Re #1182:

  • Added video stream interface in vid_stream.h, the video stream will be able to handle different video formats in encoding and decoding direction.
  • Renamed video device stream class identifiers from 'pjmedia_vid_stream*' to 'pjmedia_vid_dev_stream*' as 'pjmedia_vid_stream' is used by video stream interface.
  • Added ffmpeg video capability to be able to parse SDP format param for H263 and also decide video format for encoding direction based on remote preference and local format-capability setting.
  • Added some new APIs in jitter buffer for handling video stream: pjmedia_jbuf_put_frame3(), pjmedia_jbuf_get_frame3(), pjmedia_jbuf_peek_frame(), and pjmedia_jbuf_remove_frame().
  • Moved pjmedia_stream_info_from_sdp() from session to stream
Location:
pjproject/branches/projects/2.0-dev/pjmedia
Files:
2 added
19 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjmedia/build/pjmedia.vcproj

    r3394 r3420  
    43134313                        </File> 
    43144314                        <File 
    4315                                 RelativePath="..\src\pjmedia\session.c" 
     4315                                RelativePath="..\src\pjmedia\silencedet.c" 
    43164316                                > 
    43174317                                <FileConfiguration 
     
    43714371                        </File> 
    43724372                        <File 
    4373                                 RelativePath="..\src\pjmedia\silencedet.c" 
     4373                                RelativePath="..\src\pjmedia\sound_legacy.c" 
     4374                                > 
     4375                        </File> 
     4376                        <File 
     4377                                RelativePath="..\src\pjmedia\sound_port.c" 
    43744378                                > 
    43754379                                <FileConfiguration 
     
    44294433                        </File> 
    44304434                        <File 
    4431                                 RelativePath="..\src\pjmedia\sound_legacy.c" 
    4432                                 > 
    4433                         </File> 
    4434                         <File 
    4435                                 RelativePath="..\src\pjmedia\sound_port.c" 
     4435                                RelativePath="..\src\pjmedia\splitcomb.c" 
    44364436                                > 
    44374437                                <FileConfiguration 
     
    44914491                        </File> 
    44924492                        <File 
    4493                                 RelativePath="..\src\pjmedia\splitcomb.c" 
     4493                                RelativePath="..\src\pjmedia\stereo_port.c" 
     4494                                > 
     4495                        </File> 
     4496                        <File 
     4497                                RelativePath="..\src\pjmedia\stream.c" 
    44944498                                > 
    44954499                                <FileConfiguration 
     
    45494553                        </File> 
    45504554                        <File 
    4551                                 RelativePath="..\src\pjmedia\stereo_port.c" 
    4552                                 > 
    4553                         </File> 
    4554                         <File 
    4555                                 RelativePath="..\src\pjmedia\stream.c" 
     4555                                RelativePath="..\src\pjmedia\stream_common.c" 
     4556                                > 
     4557                        </File> 
     4558                        <File 
     4559                                RelativePath="..\src\pjmedia\tonegen.c" 
    45564560                                > 
    45574561                                <FileConfiguration 
     
    46114615                        </File> 
    46124616                        <File 
    4613                                 RelativePath="..\src\pjmedia\tonegen.c" 
     4617                                RelativePath="..\src\pjmedia\transport_adapter_sample.c" 
     4618                                > 
     4619                        </File> 
     4620                        <File 
     4621                                RelativePath="..\src\pjmedia\transport_ice.c" 
     4622                                > 
     4623                        </File> 
     4624                        <File 
     4625                                RelativePath="..\src\pjmedia\transport_loop.c" 
     4626                                > 
     4627                        </File> 
     4628                        <File 
     4629                                RelativePath="..\src\pjmedia\transport_srtp.c" 
     4630                                > 
     4631                        </File> 
     4632                        <File 
     4633                                RelativePath="..\src\pjmedia\transport_udp.c" 
    46144634                                > 
    46154635                                <FileConfiguration 
     
    46694689                        </File> 
    46704690                        <File 
    4671                                 RelativePath="..\src\pjmedia\transport_adapter_sample.c" 
    4672                                 > 
    4673                         </File> 
    4674                         <File 
    4675                                 RelativePath="..\src\pjmedia\transport_ice.c" 
    4676                                 > 
    4677                         </File> 
    4678                         <File 
    4679                                 RelativePath="..\src\pjmedia\transport_loop.c" 
    4680                                 > 
    4681                         </File> 
    4682                         <File 
    4683                                 RelativePath="..\src\pjmedia\transport_srtp.c" 
    4684                                 > 
    4685                         </File> 
    4686                         <File 
    4687                                 RelativePath="..\src\pjmedia\transport_udp.c" 
    4688                                 > 
    4689                                 <FileConfiguration 
    4690                                         Name="Release|Win32" 
    4691                                         > 
    4692                                         <Tool 
    4693                                                 Name="VCCLCompilerTool" 
    4694                                                 AdditionalIncludeDirectories="" 
    4695                                                 PreprocessorDefinitions="" 
    4696                                         /> 
    4697                                 </FileConfiguration> 
    4698                                 <FileConfiguration 
    4699                                         Name="Debug|Win32" 
    4700                                         > 
    4701                                         <Tool 
    4702                                                 Name="VCCLCompilerTool" 
    4703                                                 AdditionalIncludeDirectories="" 
    4704                                                 PreprocessorDefinitions="" 
    4705                                         /> 
    4706                                 </FileConfiguration> 
    4707                                 <FileConfiguration 
    4708                                         Name="Debug-Static|Win32" 
    4709                                         > 
    4710                                         <Tool 
    4711                                                 Name="VCCLCompilerTool" 
    4712                                                 AdditionalIncludeDirectories="" 
    4713                                                 PreprocessorDefinitions="" 
    4714                                         /> 
    4715                                 </FileConfiguration> 
    4716                                 <FileConfiguration 
    4717                                         Name="Release-Dynamic|Win32" 
    4718                                         > 
    4719                                         <Tool 
    4720                                                 Name="VCCLCompilerTool" 
    4721                                                 AdditionalIncludeDirectories="" 
    4722                                                 PreprocessorDefinitions="" 
    4723                                         /> 
    4724                                 </FileConfiguration> 
    4725                                 <FileConfiguration 
    4726                                         Name="Debug-Dynamic|Win32" 
    4727                                         > 
    4728                                         <Tool 
    4729                                                 Name="VCCLCompilerTool" 
    4730                                                 AdditionalIncludeDirectories="" 
    4731                                                 PreprocessorDefinitions="" 
    4732                                         /> 
    4733                                 </FileConfiguration> 
    4734                                 <FileConfiguration 
    4735                                         Name="Release-Static|Win32" 
    4736                                         > 
    4737                                         <Tool 
    4738                                                 Name="VCCLCompilerTool" 
    4739                                                 AdditionalIncludeDirectories="" 
    4740                                                 PreprocessorDefinitions="" 
    4741                                         /> 
    4742                                 </FileConfiguration> 
    4743                         </File> 
    4744                         <File 
    47454691                                RelativePath="..\src\pjmedia\vid_codec.c" 
     4692                                > 
     4693                        </File> 
     4694                        <File 
     4695                                RelativePath="..\src\pjmedia\vid_stream.c" 
    47464696                                > 
    47474697                        </File> 
     
    51205070                        </File> 
    51215071                        <File 
    5122                                 RelativePath="..\include\pjmedia\session.h" 
    5123                                 > 
    5124                         </File> 
    5125                         <File 
    51265072                                RelativePath="..\include\pjmedia\silencedet.h" 
    51275073                                > 
     
    51485094                        </File> 
    51495095                        <File 
     5096                                RelativePath="..\include\pjmedia\stream_common.h" 
     5097                                > 
     5098                        </File> 
     5099                        <File 
    51505100                                RelativePath="..\include\pjmedia\tonegen.h" 
    51515101                                > 
     
    51815131                        <File 
    51825132                                RelativePath="..\include\pjmedia\vid_codec.h" 
     5133                                > 
     5134                        </File> 
     5135                        <File 
     5136                                RelativePath="..\include\pjmedia\vid_stream.h" 
    51835137                                > 
    51845138                        </File> 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev.h

    r3401 r3420  
    7979 * 
    8080 * Once video stream is running, application can also retrieve or set some 
    81  * specific video capability, by using #pjmedia_vid_stream_get_cap() and 
    82  * #pjmedia_vid_stream_set_cap() and specifying the desired capability. The 
     81 * specific video capability, by using #pjmedia_vid_dev_stream_get_cap() and 
     82 * #pjmedia_vid_dev_stream_set_cap() and specifying the desired capability. The 
    8383 * value of the capability is specified as pointer, and application needs to 
    8484 * supply the pointer with the correct value, according to the documentation 
     
    155155 
    156156 
    157 /** Forward declaration for pjmedia_vid_stream */ 
    158 typedef struct pjmedia_vid_stream pjmedia_vid_stream; 
     157/** Forward declaration for pjmedia_vid_dev_stream */ 
     158typedef struct pjmedia_vid_dev_stream pjmedia_vid_dev_stream; 
    159159 
    160160typedef enum pjmedia_event_type 
     
    188188    *                      stream to stop 
    189189    */ 
    190     pj_status_t (*capture_cb)(pjmedia_vid_stream *stream, 
     190    pj_status_t (*capture_cb)(pjmedia_vid_dev_stream *stream, 
    191191                              void *user_data, 
    192192                              pjmedia_frame *frame); 
     
    211211    *                      stream to stop 
    212212    */ 
    213     pj_status_t (*render_cb)(pjmedia_vid_stream *stream, 
     213    pj_status_t (*render_cb)(pjmedia_vid_dev_stream *stream, 
    214214                             void *user_data, 
    215215                             pjmedia_frame *frame); 
     
    227227    *                      video stream will ignore the particular event. 
    228228    */ 
    229     pj_status_t (*on_event_cb)(pjmedia_vid_stream *stream, 
     229    pj_status_t (*on_event_cb)(pjmedia_vid_dev_stream *stream, 
    230230                               void *user_data, 
    231231                               pjmedia_vid_event *event); 
     
    477477 *                      error code. 
    478478 */ 
    479 PJ_DECL(pj_status_t) pjmedia_vid_stream_create(const pjmedia_vid_param *param, 
    480                                                const pjmedia_vid_cb *cb, 
    481                                                void *user_data, 
    482                                                pjmedia_vid_stream **p_strm); 
     479PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_create( 
     480                                            const pjmedia_vid_param *param, 
     481                                            const pjmedia_vid_cb *cb, 
     482                                            void *user_data, 
     483                                            pjmedia_vid_dev_stream **p_strm); 
    483484 
    484485/** 
     
    492493 *                  error code. 
    493494 */ 
    494 PJ_DECL(pj_status_t) pjmedia_vid_stream_get_param(pjmedia_vid_stream *strm, 
    495                                                   pjmedia_vid_param *param); 
     495PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_param( 
     496                                            pjmedia_vid_dev_stream *strm, 
     497                                            pjmedia_vid_param *param); 
    496498 
    497499/** 
     
    508510 *                  error code. 
    509511 */ 
    510 PJ_DECL(pj_status_t) pjmedia_vid_stream_get_cap(pjmedia_vid_stream *strm, 
    511                                                 pjmedia_vid_dev_cap cap, 
    512                                                 void *value); 
     512PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_cap( 
     513                                            pjmedia_vid_dev_stream *strm, 
     514                                            pjmedia_vid_dev_cap cap, 
     515                                            void *value); 
    513516 
    514517/** 
     
    523526 *                  error code. 
    524527 */ 
    525 PJ_DECL(pj_status_t) pjmedia_vid_stream_set_cap(pjmedia_vid_stream *strm, 
    526                                                 pjmedia_vid_dev_cap cap, 
    527                                                 const void *value); 
     528PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_set_cap( 
     529                                            pjmedia_vid_dev_stream *strm, 
     530                                            pjmedia_vid_dev_cap cap, 
     531                                            const void *value); 
    528532 
    529533/** 
     
    535539 *                  error code. 
    536540 */ 
    537 PJ_DECL(pj_status_t) pjmedia_vid_stream_start(pjmedia_vid_stream *strm); 
     541PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_start( 
     542                                            pjmedia_vid_dev_stream *strm); 
    538543 
    539544/* Get/put frame API for passive stream */ 
    540 PJ_DECL(pj_status_t) pjmedia_vid_stream_get_frame(pjmedia_vid_stream *strm, 
    541                                                   pjmedia_frame *frame); 
    542  
    543 PJ_DECL(pj_status_t) pjmedia_vid_stream_put_frame(pjmedia_vid_stream *strm, 
    544                                                   const pjmedia_frame *frame); 
     545PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame( 
     546                                            pjmedia_vid_dev_stream *strm, 
     547                                            pjmedia_frame *frame); 
     548 
     549PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_put_frame( 
     550                                            pjmedia_vid_dev_stream *strm, 
     551                                            const pjmedia_frame *frame); 
    545552 
    546553/** 
     
    552559 *                  error code. 
    553560 */ 
    554 PJ_DECL(pj_status_t) pjmedia_vid_stream_stop(pjmedia_vid_stream *strm); 
     561PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_stop( 
     562                                            pjmedia_vid_dev_stream *strm); 
    555563 
    556564/** 
     
    562570 *                  error code. 
    563571 */ 
    564 PJ_DECL(pj_status_t) pjmedia_vid_stream_destroy(pjmedia_vid_stream *strm); 
     572PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_destroy( 
     573                                            pjmedia_vid_dev_stream *strm); 
    565574 
    566575 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev_imp.h

    r3392 r3420  
    8484    /** 
    8585     * Open the video device and create video stream. See 
    86      * #pjmedia_vid_stream_create() 
     86     * #pjmedia_vid_dev_stream_create() 
    8787     */ 
    8888    pj_status_t (*create_stream)(pjmedia_vid_dev_factory *f, 
     
    9090                                 const pjmedia_vid_cb *cb, 
    9191                                 void *user_data, 
    92                                  pjmedia_vid_stream **p_vid_strm); 
     92                                 pjmedia_vid_dev_stream **p_vid_strm); 
    9393 
    9494} pjmedia_vid_dev_factory_op; 
     
    114114 * Video stream operations. 
    115115 */ 
    116 typedef struct pjmedia_vid_stream_op 
     116typedef struct pjmedia_vid_dev_stream_op 
    117117{ 
    118118    /** 
    119      * See #pjmedia_vid_stream_get_param() 
     119     * See #pjmedia_vid_dev_stream_get_param() 
    120120     */ 
    121     pj_status_t (*get_param)(pjmedia_vid_stream *strm, 
     121    pj_status_t (*get_param)(pjmedia_vid_dev_stream *strm, 
    122122                             pjmedia_vid_param *param); 
    123123 
    124124    /** 
    125      * See #pjmedia_vid_stream_get_cap() 
     125     * See #pjmedia_vid_dev_stream_get_cap() 
    126126     */ 
    127     pj_status_t (*get_cap)(pjmedia_vid_stream *strm, 
     127    pj_status_t (*get_cap)(pjmedia_vid_dev_stream *strm, 
    128128                           pjmedia_vid_dev_cap cap, 
    129129                           void *value); 
    130130 
    131131    /** 
    132      * See #pjmedia_vid_stream_set_cap() 
     132     * See #pjmedia_vid_dev_stream_set_cap() 
    133133     */ 
    134     pj_status_t (*set_cap)(pjmedia_vid_stream *strm, 
     134    pj_status_t (*set_cap)(pjmedia_vid_dev_stream *strm, 
    135135                           pjmedia_vid_dev_cap cap, 
    136136                           const void *value); 
    137137 
    138138    /** 
    139      * See #pjmedia_vid_stream_start() 
     139     * See #pjmedia_vid_dev_stream_start() 
    140140     */ 
    141     pj_status_t (*start)(pjmedia_vid_stream *strm); 
     141    pj_status_t (*start)(pjmedia_vid_dev_stream *strm); 
    142142 
    143143    /** 
    144      * See #pjmedia_vid_stream_get_frame() 
     144     * See #pjmedia_vid_dev_stream_get_frame() 
    145145     */ 
    146     pj_status_t (*get_frame)(pjmedia_vid_stream *strm, 
     146    pj_status_t (*get_frame)(pjmedia_vid_dev_stream *strm, 
    147147                             pjmedia_frame *frame); 
    148148 
    149149    /** 
    150      * See #pjmedia_vid_stream_put_frame() 
     150     * See #pjmedia_vid_dev_stream_put_frame() 
    151151     */ 
    152     pj_status_t (*put_frame)(pjmedia_vid_stream *strm, 
     152    pj_status_t (*put_frame)(pjmedia_vid_dev_stream *strm, 
    153153                             const pjmedia_frame *frame); 
    154154 
    155155    /** 
    156      * See #pjmedia_vid_stream_stop(). 
     156     * See #pjmedia_vid_dev_stream_stop(). 
    157157     */ 
    158     pj_status_t (*stop)(pjmedia_vid_stream *strm); 
     158    pj_status_t (*stop)(pjmedia_vid_dev_stream *strm); 
    159159 
    160160    /** 
    161      * See #pjmedia_vid_stream_destroy(). 
     161     * See #pjmedia_vid_dev_stream_destroy(). 
    162162     */ 
    163     pj_status_t (*destroy)(pjmedia_vid_stream *strm); 
     163    pj_status_t (*destroy)(pjmedia_vid_dev_stream *strm); 
    164164 
    165 } pjmedia_vid_stream_op; 
     165} pjmedia_vid_dev_stream_op; 
    166166 
    167167 
     
    169169 * This structure describes the video device stream. 
    170170 */ 
    171 struct pjmedia_vid_stream 
     171struct pjmedia_vid_dev_stream 
    172172{ 
    173173    /** Internal data to be initialized by video subsystem */ 
     
    178178 
    179179    /** Operations */ 
    180     pjmedia_vid_stream_op *op; 
     180    pjmedia_vid_dev_stream_op *op; 
    181181}; 
    182182 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia.h

    r3392 r3420  
    5353#include <pjmedia/sdp.h> 
    5454#include <pjmedia/sdp_neg.h> 
    55 #include <pjmedia/session.h> 
     55//#include <pjmedia/session.h> 
    5656#include <pjmedia/silencedet.h> 
    5757#include <pjmedia/sound.h> 
     
    6060#include <pjmedia/stereo.h> 
    6161#include <pjmedia/stream.h> 
     62#include <pjmedia/stream_common.h> 
    6263#include <pjmedia/tonegen.h> 
    6364#include <pjmedia/transport.h> 
     
    6970#include <pjmedia/videoport.h> 
    7071#include <pjmedia/vid_codec.h> 
     72#include <pjmedia/vid_stream.h> 
    7173#include <pjmedia/wav_playlist.h> 
    7274#include <pjmedia/wav_port.h> 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/config.h

    r3402 r3420  
    980980 
    981981/** 
     982 * Maximum video frame size. 
     983 * Default: 16kB 
     984 */ 
     985#ifndef PJMEDIA_MAX_VIDEO_FRAME_SIZE                     
     986#  define PJMEDIA_MAX_VIDEO_FRAME_SIZE                  (1<<14) 
     987#endif 
     988 
     989 
     990/** 
    982991 * Specify the maximum duration (in ms) for resynchronization. When a media 
    983992 * is late to another media it is supposed to be synchronized to, it is 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/jbuf.h

    r3065 r3420  
    6969 * This structure describes jitter buffer state. 
    7070 */ 
    71 struct pjmedia_jb_state 
     71typedef struct pjmedia_jb_state 
    7272{ 
    7373    /* Setting */ 
     
    9090    unsigned    discard;            /**< Number of discarded frames.        */ 
    9191    unsigned    empty;              /**< Number of empty on GET events.     */ 
    92 }; 
    93  
    94  
    95 /** 
    96  * @see pjmedia_jb_state 
    97  */ 
    98 typedef struct pjmedia_jb_state pjmedia_jb_state; 
     92} pjmedia_jb_state; 
    9993 
    10094 
     
    181175 
    182176/** 
     177 * Enable/disable the jitter buffer drift detection and handling mechanism. 
     178 * The default behavior is enabled. 
     179 * 
     180 * @param jb            The jitter buffer 
     181 * @param enable        Set to PJ_TRUE to enable or PJ_FALSE to disable. 
     182 * 
     183 * @return              PJ_SUCCESS on success. 
     184 */ 
     185PJ_DECL(pj_status_t) pjmedia_jbuf_enable_discard(pjmedia_jbuf *jb, 
     186                                                 pj_bool_t enable); 
     187 
     188 
     189/** 
    183190 * Destroy jitter buffer instance. 
    184191 * 
     
    244251                                       pj_bool_t *discarded); 
    245252 
     253/** 
     254 * Put a frame to the jitter buffer. If the frame can be accepted (based 
     255 * on the sequence number), the jitter buffer will copy the frame and put 
     256 * it in the appropriate position in the buffer. 
     257 * 
     258 * Application MUST manage it's own synchronization when multiple threads 
     259 * are accessing the jitter buffer at the same time. 
     260 * 
     261 * @param jb            The jitter buffer. 
     262 * @param frame         Pointer to frame buffer to be stored in the jitter 
     263 *                      buffer. 
     264 * @param size          The frame size. 
     265 * @param bit_info      Bit precise info of the frame, e.g: a frame may not  
     266 *                      exactly start and end at the octet boundary, so this 
     267 *                      field may be used for specifying start & end bit offset. 
     268 * @param frame_seq     The frame sequence number. 
     269 * @param frame_ts      The frame timestamp. 
     270 * @param discarded     Flag whether the frame is discarded by jitter buffer. 
     271 */ 
     272PJ_DECL(void) pjmedia_jbuf_put_frame3( pjmedia_jbuf *jb,  
     273                                       const void *frame,  
     274                                       pj_size_t size,  
     275                                       pj_uint32_t bit_info, 
     276                                       int frame_seq, 
     277                                       pj_uint32_t frame_ts, 
     278                                       pj_bool_t *discarded); 
    246279/** 
    247280 * Get a frame from the jitter buffer. The jitter buffer will return the 
     
    294327 
    295328 
     329PJ_DECL(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,  
     330                                      void *frame,  
     331                                      pj_size_t *size,  
     332                                      char *p_frm_type, 
     333                                      pj_uint32_t *bit_info, 
     334                                      pj_uint32_t *ts); 
     335 
     336PJ_DECL(void) pjmedia_jbuf_peek_frame(pjmedia_jbuf *jb, 
     337                                      unsigned idx, 
     338                                      const void **frame,  
     339                                      pj_size_t *size,  
     340                                      char *p_frm_type, 
     341                                      pj_uint32_t *bit_info, 
     342                                      pj_uint32_t *ts); 
     343 
     344PJ_DECL(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb,  
     345                                            unsigned frame_cnt); 
     346 
     347 
    296348/** 
    297349 * Get jitter buffer current state/settings. 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/stream.h

    r3418 r3420  
    144144 
    145145 
     146/** 
     147 * This function will initialize the stream info based on information 
     148 * in both SDP session descriptors for the specified stream index.  
     149 * The remaining information will be taken from default codec parameters.  
     150 * If socket info array is specified, the socket will be copied to the  
     151 * session info as well. 
     152 * 
     153 * @param si            Stream info structure to be initialized. 
     154 * @param pool          Pool to allocate memory. 
     155 * @param endpt         PJMEDIA endpoint instance. 
     156 * @param local         Local SDP session descriptor. 
     157 * @param remote        Remote SDP session descriptor. 
     158 * @param stream_idx    Media stream index in the session descriptor. 
     159 * 
     160 * @return              PJ_SUCCESS if stream info is successfully initialized. 
     161 */ 
     162PJ_DECL(pj_status_t) 
     163pjmedia_stream_info_from_sdp( pjmedia_stream_info *si, 
     164                              pj_pool_t *pool, 
     165                              pjmedia_endpt *endpt, 
     166                              const pjmedia_sdp_session *local, 
     167                              const pjmedia_sdp_session *remote, 
     168                              unsigned stream_idx); 
     169 
    146170 
    147171/** 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/vid_codec.h

    r3392 r3420  
    2323 
    2424/** 
    25  * @file codec.h 
    26  * @brief Codec framework. 
     25 * @file vid_codec.h 
     26 * @brief Video codec framework. 
    2727 */ 
    2828 
     
    4646    pjmedia_format_id   fmt_id;         /**< Encoded format ID              */ 
    4747    pj_str_t            encoding_name;  /**< Encoding name                  */ 
     48    unsigned            pt;             /**< Payload type (may be 255 for 
     49                                             dynamic payload type)          */ 
     50    unsigned            clock_rate;     /**< Clock rate                     */ 
    4851    pjmedia_dir         dir;            /**< Direction                      */ 
    49     unsigned            pt;             /**< Payload type (may be 0 for 
    50                                              dynamic payload type)          */ 
    51     unsigned            clock_rate;     /**< (?) Clock rate                 */ 
    52     unsigned            dec_fmt_id_cnt; 
     52    unsigned            dec_fmt_id_cnt; /**< # of supported encoding source  
     53                                             format IDs                     */ 
    5354    pjmedia_format_id   dec_fmt_id[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT]; 
    5455                                        /**< Supported encoding source  
    5556                                             format IDs                     */ 
    56     unsigned            fps_cnt;        /**< zero if support any fps        */ 
    57     pjmedia_ratio       fps[PJMEDIA_VID_CODEC_MAX_FPS_CNT];     
    58                                         /**< (?) supported FPSes,  
    59                                              ffmpeg has this                */ 
     57    unsigned            fps_cnt;        /**< # of supported frame-rates, can be 
     58                                             zero (support any frame-rate)  */ 
     59    pjmedia_ratio       fps[PJMEDIA_VID_CODEC_MAX_FPS_CNT]; 
     60                                        /**< Supported frame-rates          */ 
    6061} pjmedia_vid_codec_info; 
     62 
    6163 
    6264/**  
     
    8082 
    8183    unsigned            enc_mtu;        /**< MTU or max payload size setting*/ 
    82     unsigned            pt;             /**< Payload type.                  */ 
    8384} pjmedia_vid_codec_param; 
    8485 
    8586 
    86  
    87 /* 
    88  * Forward declaration for pjmedia_vid_codec. 
     87/** 
     88 * Enumeration of video codec events. 
     89 */ 
     90typedef enum pjmedia_vid_codec_event 
     91{ 
     92    /** 
     93     * Format changed event. The decoder output format is not really 
     94     * configurable, so that the output format setting configured in the 
     95     * initialization may be changed. Application can catch this event 
     96     * by checking the bit_info field of the pjmedia_frame of the decoder 
     97     * output frame. 
     98     */ 
     99    PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED = 1, 
     100 
     101} pjmedia_vid_codec_event; 
     102 
     103 
     104/** 
     105 * Forward declaration for video codec. 
    89106 */ 
    90107typedef struct pjmedia_vid_codec pjmedia_vid_codec; 
     
    112129     * Open the codec and initialize with the specified parameter. 
    113130     * Upon successful initialization, the codec may modify the parameter 
    114      * and fills in the unspecified values (such as enc_ptime, when 
    115      * encoder ptime is different than decoder ptime). 
     131     * and fills in the unspecified values (such as size or frame rate of 
     132     * the encoder format, as it may need to be negotiated with remote 
     133     * preferences via SDP fmtp). 
    116134     * 
    117135     * @param codec     The codec instance. 
     
    139157     * non-PJ_SUCCESS, and the original parameters will not be changed. 
    140158     * 
    141      * Application can expect changing trivial codec settings such as 
    142      * changing VAD setting to succeed. 
    143      * 
    144159     * @param codec     The codec instance. 
    145160     * @param param     The new codec parameter. 
     
    148163     */ 
    149164    pj_status_t (*modify)(pjmedia_vid_codec *codec,  
    150                           const pjmedia_vid_codec_param *param ); 
     165                          const pjmedia_vid_codec_param *param); 
     166 
     167    /**  
     168     * Get the codec parameter after the codec is opened.  
     169     * 
     170     * @param codec     The codec instance. 
     171     * @param param     The codec parameter. 
     172     * 
     173     * @return          PJ_SUCCESS on success. 
     174     */ 
     175    pj_status_t (*get_param)(pjmedia_vid_codec *codec, 
     176                             pjmedia_vid_codec_param *param); 
    151177 
    152178    /** 
    153      * Instruct the codec to inspect the specified payload/packet and 
    154      * split the packet into individual base frames. Each output frames will 
    155      * have ptime that is equal to basic frame ptime (i.e. the value of 
    156      * info.frm_ptime in #pjmedia_vid_codec_param). 
     179     * Instruct the codec to generate a payload/packet from a picture 
     180     * bitstream to be sent (via network). The maximum payload size or 
     181     * MTU is configurable via enc_mtu field of #pjmedia_vid_codec_param. 
     182     * For a long bitstream, application usually need to call this function 
     183     * multiple times until the whole bitstream is sent. Note that, for 
     184     * performance reason, the packetization will be done in-place, so the 
     185     * original bitstream may be modified by this function. 
     186     * 
     187     * @param codec     The codec instance 
     188     * @param bits      The picture bitstream. 
     189     * @param bits_len  The length of the bitstream. 
     190     * @param bits_pos  On input, the start position of the bitstream 
     191     *                  to be packetized. On output, the next position for 
     192     *                  next packet. 
     193     * @param pkt       The pointer of the generated payload. 
     194     * @param pkt_len   The payload length. 
     195     * 
     196     * @return          PJ_SUCCESS on success. 
     197     */ 
     198    pj_status_t (*packetize) (pjmedia_vid_codec *codec, 
     199                              pj_uint8_t *bits, 
     200                              pj_size_t bits_len, 
     201                              unsigned *bits_pos, 
     202                              const pj_uint8_t **pkt, 
     203                              pj_size_t *pkt_len); 
     204 
     205    /** 
     206     * Instruct the codec to parse a payload and append it into a picture 
     207     * bitstream. A picture bitstreams may need to be reconstructed from 
     208     * one or more payloads. Note that this function will not provide the 
     209     * detection of picture boundary, so application should manage the 
     210     * picture boundary detection by itself, e.g: for RTP delivery, payloads 
     211     * belong to the same picture will share the same RTP timestamp and also 
     212     * there is marker bit in the RTP header that is usually reserved for 
     213     * end-of-picture flag. 
    157214     * 
    158215     * @param codec     The codec instance 
     
    168225     * @return          PJ_SUCCESS on success. 
    169226     */ 
    170     pj_status_t (*packetize) (pjmedia_vid_codec *codec, 
    171                               pj_uint8_t *buf, 
    172                               pj_size_t buf_len, 
    173                               unsigned *pos, 
    174                               const pj_uint8_t **payload, 
    175                               pj_size_t *payload_len); 
    176  
    177     /** 
    178      * Instruct the codec to inspect the specified payload/packet and 
    179      * split the packet into individual base frames. Each output frames will 
    180      * have ptime that is equal to basic frame ptime (i.e. the value of 
    181      * info.frm_ptime in #pjmedia_vid_codec_param). 
    182      * 
    183      * @param codec     The codec instance 
    184      * @param pkt       The input packet. 
    185      * @param pkt_size  Size of the packet. 
    186      * @param timestamp The timestamp of the first sample in the packet. 
    187      * @param frame_cnt On input, specifies the maximum number of frames 
    188      *                  in the array. On output, the codec must fill 
    189      *                  with number of frames detected in the packet. 
    190      * @param frames    On output, specifies the frames that have been 
    191      *                  detected in the packet. 
    192      * 
    193      * @return          PJ_SUCCESS on success. 
    194      */ 
    195227    pj_status_t (*unpacketize)(pjmedia_vid_codec *codec, 
    196228                               const pj_uint8_t *payload, 
    197229                               pj_size_t   payload_len, 
    198                                pj_uint8_t *buf, 
    199                                pj_size_t  *buf_len); 
     230                               pj_uint8_t *bits, 
     231                               pj_size_t  *bits_len); 
    200232 
    201233    /**  
    202234     * Instruct the codec to encode the specified input frame. The input 
    203      * PCM samples MUST have ptime that is multiplication of base frame 
    204      * ptime (i.e. the value of info.frm_ptime in #pjmedia_vid_codec_param). 
     235     * MUST contain only one picture with appropriate format as specified 
     236     * in opening the codec. 
    205237     * 
    206238     * @param codec     The codec instance. 
     
    218250    /**  
    219251     * Instruct the codec to decode the specified input frame. The input 
    220      * frame MUST have ptime that is exactly equal to base frame 
    221      * ptime (i.e. the value of info.frm_ptime in #pjmedia_vid_codec_param). 
    222      * Application can achieve this by parsing the packet into base 
    223      * frames before decoding each frame. 
     252     * frame MUST contain exactly one picture. Note that the decoded picture 
     253     * format may different to the current setting, e.g: the format specified 
     254     * in the #pjmedia_vid_codec_param when opening the codec, in this case the 
     255     * PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED flag will be set in the bit_info 
     256     * field of the output frame and application can query the new format 
     257     * using #get_param(). 
    224258     * 
    225259     * @param codec     The codec instance. 
     
    248282                           unsigned out_size, 
    249283                           pjmedia_frame *output); 
     284 
    250285} pjmedia_vid_codec_op; 
    251286 
     
    259294 
    260295/** 
    261  * This structure describes a codec instance.  
     296 * This structure describes a video codec instance.  
    262297 */ 
    263298struct pjmedia_vid_codec 
     
    267302 
    268303    /** Codec's private data. */ 
    269     void                    *codec_data; 
     304    void                        *codec_data; 
    270305 
    271306    /** Codec factory where this codec was allocated. */ 
     
    273308 
    274309    /** Operations to codec. */ 
    275     pjmedia_vid_codec_op            *op; 
     310    pjmedia_vid_codec_op        *op; 
    276311}; 
    277312 
     
    377412 
    378413/** 
     414 * Opaque declaration for codec manager. 
     415 */ 
     416typedef struct pjmedia_vid_codec_mgr pjmedia_vid_codec_mgr; 
     417 
     418/** 
    379419 * Declare maximum codecs 
    380420 */ 
     
    382422 
    383423 
    384 /**  
    385  * Codec manager maintains array of these structs for each supported 
    386  * codec. 
    387  */ 
    388 typedef struct pjmedia_vid_codec_desc 
    389 { 
    390     pjmedia_vid_codec_info           info;      /**< Codec info.            */ 
    391     pjmedia_codec_id                 id;        /**< Fully qualified name   */ 
    392     pjmedia_codec_priority           prio;      /**< Priority.              */ 
    393     pjmedia_vid_codec_factory       *factory;   /**< The factory.           */ 
    394     pjmedia_vid_codec_param         *def_param; /**< Default codecs  
    395                                                      parameters.            */ 
    396 } pjmedia_vid_codec_desc; 
    397  
    398  
    399 /** 
    400  * The declaration for codec manager. Application doesn't normally need 
    401  * to see this declaration, but nevertheless this declaration is needed 
    402  * by media endpoint to instantiate the codec manager. 
    403  */ 
    404 typedef struct pjmedia_vid_codec_mgr 
    405 { 
    406     /** Codec manager mutex. */ 
    407     pj_mutex_t                  *mutex; 
    408  
    409     /** List of codec factories registered to codec manager. */ 
    410     pjmedia_vid_codec_factory    factory_list; 
    411  
    412     /** Number of supported codecs. */ 
    413     unsigned                     codec_cnt; 
    414  
    415     /** Array of codec descriptor. */ 
    416     pjmedia_vid_codec_desc       codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS]; 
    417  
    418 } pjmedia_vid_codec_mgr; 
    419  
    420  
    421  
    422 /** 
    423  * Initialize codec manager. Normally this function is called by pjmedia 
     424 
     425/** 
     426 * Initialize codec manager. If there is no the default video codec manager, 
     427 * this function will automatically set the default video codec manager to 
     428 * the new codec manager instance. Normally this function is called by pjmedia 
    424429 * endpoint's initialization code. 
    425430 * 
    426  * @param mgr       Codec manager instance. 
    427  * @param pf        Pool factory instance. 
     431 * @param pool      The pool instance. 
     432 * @param mgr       The pointer to the new codec manager instance. 
    428433 * 
    429434 * @return          PJ_SUCCESS on success. 
     
    437442 * endpoint's deinitialization code. 
    438443 * 
    439  * @param mgr       Codec manager instance. 
     444 * @param mgr       Codec manager instance.  If NULL, it is the default codec 
     445 *                  manager instance will be destroyed. 
    440446 * 
    441447 * @return          PJ_SUCCESS on success. 
     
    443449PJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr *mgr); 
    444450 
     451 
     452/** 
     453 * Get the default codec manager instance. 
     454 * 
     455 * @return          The default codec manager instance or NULL if none. 
     456 */ 
    445457PJ_DECL(pjmedia_vid_codec_mgr*) pjmedia_vid_codec_mgr_instance(void); 
     458 
     459 
     460/** 
     461 * Set the default codec manager instance. 
     462 * 
     463 * @param mgr       The codec manager instance. 
     464 */ 
    446465PJ_DECL(void) pjmedia_vid_codec_mgr_set_instance(pjmedia_vid_codec_mgr* mgr); 
    447466 
     
    451470 * all supported codecs in the factory to the codec manager. 
    452471 * 
    453  * @param mgr       The codec manager instance. Application can get the 
    454  *                  instance by calling #pjmedia_endpt_get_codec_mgr(). 
     472 * @param mgr       The codec manager instance. If NULL, the default codec 
     473 *                  manager instance will be used. 
    455474 * @param factory   The codec factory to be registered. 
    456475 * 
     
    466485 * codec manager's list of supported codecs. 
    467486 * 
    468  * @param mgr       The codec manager instance. Application can get the 
    469  *                  instance by calling #pjmedia_endpt_get_codec_mgr(). 
     487 * @param mgr       The codec manager instance. If NULL, the default codec 
     488 *                  manager instance will be used. 
    470489 * @param factory   The codec factory to be unregistered. 
    471490 * 
     
    480499 * codec manager by codec factories. 
    481500 * 
    482  * @param mgr       The codec manager instance. Application can get the 
    483  *                  instance by calling #pjmedia_endpt_get_codec_mgr(). 
     501 * @param mgr       The codec manager instance. If NULL, the default codec 
     502 *                  manager instance will be used. 
    484503 * @param count     On input, specifies the number of elements in 
    485504 *                  the array. On output, the value will be set to 
     
    501520 * Get codec info for the specified static payload type. 
    502521 * 
    503  * @param mgr       The codec manager instance. Application can get the 
    504  *                  instance by calling #pjmedia_endpt_get_codec_mgr(). 
     522 * @param mgr       The codec manager instance. If NULL, the default codec 
     523 *                  manager instance will be used. 
    505524 * @param pt        Static payload type/number. 
    506  * @param inf       Pointer to receive codec info. 
     525 * @param info      Pointer to receive codec info. 
    507526 * 
    508527 * @return          PJ_SUCCESS on success. 
     
    511530pjmedia_vid_codec_mgr_get_codec_info( pjmedia_vid_codec_mgr *mgr, 
    512531                                      unsigned pt, 
    513                                       const pjmedia_vid_codec_info **inf); 
     532                                      const pjmedia_vid_codec_info **info); 
    514533 
    515534/** 
    516535 * Convert codec info struct into a unique codec identifier. 
    517  * A codec identifier looks something like "L16/44100/2". 
     536 * A codec identifier looks something like "H263/90000". 
    518537 * 
    519538 * @param info      The codec info 
     
    532551 * Find codecs by the unique codec identifier. This function will find 
    533552 * all codecs that match the codec identifier prefix. For example, if 
    534  * "L16" is specified, then it will find "L16/8000/1", "L16/16000/1", 
     553 * "H26" is specified, then it will find "H263/90000", "H264/90000", 
    535554 * and so on, up to the maximum count specified in the argument. 
    536555 * 
    537  * @param mgr       The codec manager instance. Application can get the 
    538  *                  instance by calling #pjmedia_endpt_get_codec_mgr(). 
     556 * @param mgr       The codec manager instance. If NULL, the default codec 
     557 *                  manager instance will be used. 
    539558 * @param codec_id  The full codec ID or codec ID prefix. If an empty 
    540559 *                  string is given, it will match all codecs. 
     
    549568 */ 
    550569PJ_DECL(pj_status_t)  
    551 pjmedia_vid_codec_mgr_find_codecs_by_id( pjmedia_vid_codec_mgr *mgr, 
    552                                      const pj_str_t *codec_id, 
    553                                      unsigned *count, 
    554                                      const pjmedia_vid_codec_info *p_info[], 
    555                                      unsigned prio[]); 
     570pjmedia_vid_codec_mgr_find_codecs_by_id(pjmedia_vid_codec_mgr *mgr, 
     571                                        const pj_str_t *codec_id, 
     572                                        unsigned *count, 
     573                                        const pjmedia_vid_codec_info *p_info[], 
     574                                        unsigned prio[]); 
    556575 
    557576 
     
    562581 * priorities of all those codecs. 
    563582 * 
    564  * @param mgr       The codec manager instance. Application can get the 
    565  *                  instance by calling #pjmedia_endpt_get_codec_mgr(). 
     583 * @param mgr       The codec manager instance. If NULL, the default codec 
     584 *                  manager instance will be used. 
    566585 * @param codec_id  The full codec ID or codec ID prefix. If an empty 
    567586 *                  string is given, it will match all codecs. 
     
    574593PJ_DECL(pj_status_t) 
    575594pjmedia_vid_codec_mgr_set_codec_priority(pjmedia_vid_codec_mgr *mgr,  
    576                                     const pj_str_t *codec_id, 
    577                                     pj_uint8_t prio); 
     595                                        const pj_str_t *codec_id, 
     596                                        pj_uint8_t prio); 
    578597 
    579598 
     
    581600 * Get default codec param for the specified codec info. 
    582601 * 
    583  * @param mgr       The codec manager instance. Application can get the 
    584  *                  instance by calling #pjmedia_endpt_get_codec_mgr(). 
     602 * @param mgr       The codec manager instance. If NULL, the default codec 
     603 *                  manager instance will be used. 
    585604 * @param info      The codec info, which default parameter's is being 
    586605 *                  queried. 
     
    591610 */ 
    592611PJ_DECL(pj_status_t)  
    593 pjmedia_vid_codec_mgr_get_default_param( pjmedia_vid_codec_mgr *mgr, 
    594                                      const pjmedia_vid_codec_info *info, 
    595                                      pjmedia_vid_codec_param *param ); 
     612pjmedia_vid_codec_mgr_get_default_param(pjmedia_vid_codec_mgr *mgr, 
     613                                        const pjmedia_vid_codec_info *info, 
     614                                        pjmedia_vid_codec_param *param); 
    596615 
    597616 
     
    599618 * Set default codec param for the specified codec info. 
    600619 * 
    601  * @param mgr       The codec manager instance. Application can get the 
    602  *                  instance by calling #pjmedia_endpt_get_codec_mgr(). 
     620 * @param mgr       The codec manager instance. If NULL, the default codec 
     621 *                  manager instance will be used. 
     622 * @param pool      The pool instance. 
    603623 * @param info      The codec info, which default parameter's is being 
    604624 *                  updated. 
     
    620640 * until it finds factory that is able to create the specified codec. 
    621641 * 
    622  * @param mgr       The codec manager instance. Application can get the 
    623  *                  instance by calling #pjmedia_endpt_get_codec_mgr(). 
     642 * @param mgr       The codec manager instance. If NULL, the default codec 
     643 *                  manager instance will be used. 
    624644 * @param info      The information about the codec to be created. 
    625645 * @param p_codec   Pointer to receive the codec instance. 
     
    636656 * the instance of the codec back to its factory. 
    637657 * 
    638  * @param mgr       The codec manager instance. Application can get the 
    639  *                  instance by calling #pjmedia_endpt_get_codec_mgr(). 
     658 * @param mgr       The codec manager instance. If NULL, the default codec 
     659 *                  manager instance will be used. 
    640660 * @param codec     The codec instance. 
    641661 * 
     
    655675 
    656676/** 
    657  * @defgroup PJMEDIA_CODEC_CODECS Supported codecs 
     677 * @defgroup PJMEDIA_CODEC_VID_CODECS Supported video codecs 
    658678 * @ingroup PJMEDIA_CODEC 
    659  * @brief Documentation about individual codec supported by PJMEDIA 
     679 * @brief Documentation about individual video codec supported by PJMEDIA 
    660680 * @{ 
    661681 * Please see the APIs provided by the individual codecs below. 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/videoport.h

    r3402 r3420  
    109109 * @return              The video stream. 
    110110 */ 
    111 PJ_DECL(pjmedia_vid_stream*) 
     111PJ_DECL(pjmedia_vid_dev_stream*) 
    112112pjmedia_vid_port_get_stream(pjmedia_vid_port *vid_port); 
    113113 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c

    r3392 r3420  
    2828#include <pj/os.h> 
    2929 
     30 
    3031/* 
    3132 * Only build this file if PJMEDIA_HAS_FFMPEG_CODEC != 0 
     
    3839#include <libavcodec/avcodec.h> 
    3940#include <libavformat/avformat.h> 
     41#include <libswscale/swscale.h> 
    4042 
    4143 
     
    6668static pj_status_t  ffmpeg_codec_modify(pjmedia_vid_codec *codec,  
    6769                                        const pjmedia_vid_codec_param *attr ); 
     70static pj_status_t  ffmpeg_codec_get_param(pjmedia_vid_codec *codec, 
     71                                           pjmedia_vid_codec_param *param); 
    6872static pj_status_t  ffmpeg_packetize ( pjmedia_vid_codec *codec, 
    6973                                       pj_uint8_t *buf, 
     
    96100    &ffmpeg_codec_close, 
    97101    &ffmpeg_codec_modify, 
     102    &ffmpeg_codec_get_param, 
    98103    &ffmpeg_packetize, 
    99104    &ffmpeg_unpacketize, 
     
    112117    &ffmpeg_dealloc_codec 
    113118}; 
    114  
    115  
    116 typedef struct ffmpeg_codec_info { 
    117     PJ_DECL_LIST_MEMBER(struct ffmpeg_codec_info); 
    118     pjmedia_vid_codec_info       info; 
    119     AVCodec                     *enc; 
    120     AVCodec                     *dec; 
    121 } ffmpeg_codec_info; 
    122119 
    123120 
     
    129126    pj_pool_t                   *pool; 
    130127    pj_mutex_t                  *mutex; 
    131     ffmpeg_codec_info            codecs; 
    132128} ffmpeg_factory; 
    133129 
     130 
     131typedef struct ffmpeg_codec_desc ffmpeg_codec_desc; 
     132 
     133/* ITU resolution ID */ 
     134typedef enum itu_res_id { 
     135    ITU_RES_SQCIF, 
     136    ITU_RES_QCIF, 
     137    ITU_RES_CIF, 
     138    ITU_RES_4CIF, 
     139    ITU_RES_16CIF, 
     140    ITU_RES_CUSTOM, 
     141} itu_res_id; 
     142 
     143/* ITU resolution definition */ 
     144struct itu_res { 
     145    itu_res_id          id; 
     146    pj_str_t            name;     
     147    pjmedia_rect_size   size; 
     148} itu_res_def [] = 
     149{ 
     150    {ITU_RES_16CIF,     {"16CIF",5},    {1408,1142}}, 
     151    {ITU_RES_4CIF,      {"4CIF",4},     {704,576}}, 
     152    {ITU_RES_CIF,       {"CIF",3},      {352,288}}, 
     153    {ITU_RES_QCIF,      {"QCIF",4},     {176,144}}, 
     154    {ITU_RES_SQCIF,     {"SQCIF",5},    {88,72}}, 
     155    {ITU_RES_CUSTOM,    {"CUSTOM",6},   {0,0}}, 
     156}; 
    134157 
    135158/* FFMPEG codecs private data. */ 
    136159typedef struct ffmpeg_private { 
     160    const ffmpeg_codec_desc         *desc; 
     161    pjmedia_vid_codec_param          param;     /**< Codec param            */ 
     162    pj_pool_t                       *pool;      /**< Pool for each instance */ 
     163    pj_timestamp                     last_tx;   /**< Timestamp of last  
     164                                                     transmit               */ 
     165 
     166    /* Format info and apply format param */ 
     167    const pjmedia_video_format_info *enc_vfi; 
     168    pjmedia_video_apply_fmt_param    enc_vafp; 
     169    const pjmedia_video_format_info *dec_vfi; 
     170    pjmedia_video_apply_fmt_param    dec_vafp; 
     171 
     172    /* The ffmpeg codec states. */ 
     173    AVCodec                         *enc; 
     174    AVCodec                         *dec; 
     175    AVCodecContext                  *enc_ctx; 
     176    AVCodecContext                  *dec_ctx; 
     177 
     178    /* The ffmpeg decoder cannot set the output format, so format conversion 
     179     * may be needed for post-decoding. 
     180     */ 
     181    enum PixelFormat                 expected_dec_fmt; 
     182                                                /**< expected output format of  
     183                                                     ffmpeg decoder         */ 
     184    struct SwsContext               *sws_ctx;   /**< the format converter for  
     185                                                     post decoding          */ 
     186 
     187} ffmpeg_private; 
     188 
     189 
     190typedef pj_status_t (*func_packetize)   (pj_uint8_t *buf, 
     191                                         pj_size_t buf_len, 
     192                                         unsigned *pos, 
     193                                         int max_payload_len, 
     194                                         const pj_uint8_t **payload, 
     195                                         pj_size_t *payload_len); 
     196 
     197typedef pj_status_t (*func_unpacketize) (const pj_uint8_t *payload, 
     198                                         pj_size_t   payload_len, 
     199                                         pj_uint8_t *bits, 
     200                                         pj_size_t  *bits_len); 
     201 
     202typedef pj_status_t (*func_parse_fmtp)  (ffmpeg_private *ff); 
     203 
     204/* FFMPEG codec info */ 
     205struct ffmpeg_codec_desc { 
     206    /* Predefined info */ 
     207    pjmedia_vid_codec_info       info; 
     208    func_packetize               packetize; 
     209    func_unpacketize             unpacketize; 
     210    func_parse_fmtp              parse_fmtp; 
     211    pjmedia_codec_fmtp           dec_fmtp; 
     212 
     213    /* Init time defined info */ 
     214    pj_bool_t                    enabled; 
    137215    AVCodec                     *enc; 
    138216    AVCodec                     *dec; 
    139     AVCodecContext              *enc_ctx; 
    140     AVCodecContext              *dec_ctx; 
    141     AVCodecParserContext        *dec_parser_ctx; 
    142  
    143     /* 
    144     pjmedia_frame               *pack_frms; 
    145     unsigned                     pack_frm_cnt; 
    146     unsigned                     pack_frm_max_cnt; 
    147     */ 
    148  
    149     pjmedia_vid_codec_param      param;     /**< Codec param.               */ 
    150     pj_pool_t                   *pool;      /**< Pool for each instance.    */ 
    151     pj_timestamp                 last_tx;   /**< Timestamp of last transmit.*/ 
    152     const pjmedia_video_format_info *vfi; 
    153     pjmedia_video_apply_fmt_param    vafp; 
    154 } ffmpeg_private; 
     217}; 
     218 
     219/* H263 packetizer */ 
     220static pj_status_t h263_packetize(pj_uint8_t *buf, 
     221                                  pj_size_t buf_len, 
     222                                  unsigned *pos, 
     223                                  int max_payload_len, 
     224                                  const pj_uint8_t **payload, 
     225                                  pj_size_t *payload_len) 
     226{ 
     227    return pjmedia_h263_packetize(buf, buf_len, pos, max_payload_len,  
     228                                  payload, payload_len); 
     229} 
     230 
     231/* H263 unpacketizer */ 
     232static pj_status_t h263_unpacketize(const pj_uint8_t *payload, 
     233                                    pj_size_t   payload_len, 
     234                                    pj_uint8_t *bits, 
     235                                    pj_size_t  *bits_len) 
     236{ 
     237    return pjmedia_h263_unpacketize(payload, payload_len, bits, bits_len); 
     238} 
     239 
     240/* H263 fmtp parser */ 
     241static pj_status_t h263_parse_fmtp(ffmpeg_private *ff); 
     242 
     243 
     244/* Internal codec info */ 
     245ffmpeg_codec_desc codec_desc[] = 
     246{ 
     247    { 
     248        {PJMEDIA_FORMAT_H263,   {"H263",4},     PJMEDIA_RTP_PT_H263}, 
     249        &h263_packetize, &h263_unpacketize, &h263_parse_fmtp, 
     250        {2, { {{"CIF",3}, {"2",1}}, {{"QCIF",4}, {"1",1}}, } }, 
     251    }, 
     252    { 
     253        {PJMEDIA_FORMAT_H261,   {"H261",4},     PJMEDIA_RTP_PT_H261}, 
     254    }, 
     255    { 
     256        {PJMEDIA_FORMAT_MJPEG,  {"JPEG",4},     PJMEDIA_RTP_PT_JPEG}, 
     257    }, 
     258}; 
     259 
     260/* Parse fmtp value for custom resolution, e.g: "CUSTOM=800,600,2" */ 
     261static pj_status_t parse_fmtp_itu_custom_res(const pj_str_t *fmtp_val, 
     262                                             pjmedia_rect_size *size, 
     263                                             unsigned *mpi) 
     264{ 
     265    const char *p, *p_end; 
     266    pj_str_t token; 
     267    unsigned long val[3] = {0}; 
     268    unsigned i = 0; 
     269 
     270    p = token.ptr = fmtp_val->ptr; 
     271    p_end = p + fmtp_val->slen; 
     272 
     273    while (p<=p_end && i<PJ_ARRAY_SIZE(val)) { 
     274        if (*p==',' || p==p_end) { 
     275            token.slen = (char*)p - token.ptr; 
     276            val[i++] = pj_strtoul(&token); 
     277            token.ptr = (char*)p+1; 
     278        } 
     279        ++p; 
     280    } 
     281 
     282    if (!val[0] || !val[1]) 
     283        return PJ_ETOOSMALL; 
     284 
     285    if (val[2]<1 || val[2]>32) 
     286        return PJ_EINVAL; 
     287 
     288    size->w = val[0]; 
     289    size->h = val[1]; 
     290    *mpi = val[2]; 
     291    return PJ_SUCCESS; 
     292} 
     293 
     294#define CALC_ITU_CUSTOM_RES_SCORE(size, mpi) ((size)->w * (size)->h / mpi) 
     295 
     296/* ITU codec capabilities */ 
     297typedef struct itu_cap 
     298{ 
     299    /* Lowest MPI for each non-custom resolution */ 
     300    unsigned            lowest_mpi[PJ_ARRAY_SIZE(itu_res_def)]; 
     301    /* For custom resolution, we use maximum processing score */ 
     302    unsigned            custom_res_max_score; 
     303} itu_cap; 
     304 
     305 
     306static pj_status_t load_itu_cap(const pjmedia_codec_fmtp *fmtp, 
     307                                itu_cap *cap) 
     308{ 
     309    unsigned i, j; 
     310    unsigned min_mpi = 0; 
     311 
     312    /* Get Minimum Picture Interval (MPI) for each resolution. If a resolution 
     313     * has no MPI setting in fmtp, the MPI setting is derived from the higher 
     314     * resolution. 
     315     */ 
     316    for (i=0; i<PJ_ARRAY_SIZE(itu_res_def); ++i) { 
     317 
     318        /* Init lowest MPI */ 
     319        cap->lowest_mpi[i] = min_mpi? min_mpi:1; 
     320 
     321        for (j=0; j<fmtp->cnt; ++j) { 
     322            if (pj_stricmp(&fmtp->param[j].name, &itu_res_def[i].name)==0) { 
     323                pjmedia_rect_size size; 
     324                unsigned mpi; 
     325                unsigned score; 
     326 
     327                if (i != ITU_RES_CUSTOM) { 
     328                    size = itu_res_def[i].size; 
     329                    mpi = pj_strtoul(&fmtp->param[j].val); 
     330                    if (min_mpi) 
     331                        min_mpi = PJ_MIN(mpi, min_mpi); 
     332                    else 
     333                        min_mpi = mpi; 
     334 
     335                    /* Update the lowest MPI for this resolution */ 
     336                    cap->lowest_mpi[i] = min_mpi; 
     337 
     338                    /* Also update the processing score for the custom  
     339                     * resolution. 
     340                     */ 
     341                    score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 
     342                    cap->custom_res_max_score =  
     343                                    PJ_MAX(score, cap->custom_res_max_score); 
     344                } else { 
     345                     
     346 
     347                    if (parse_fmtp_itu_custom_res(&fmtp->param[j].val,  
     348                                                  &size, &mpi) == PJ_SUCCESS) 
     349                    { 
     350                        score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 
     351                        cap->custom_res_max_score =  
     352                                    PJ_MAX(score, cap->custom_res_max_score); 
     353                    } 
     354                } 
     355            } 
     356        } 
     357    } 
     358 
     359    return PJ_SUCCESS; 
     360} 
     361 
     362/* H263 fmtp parser */ 
     363static pj_status_t h263_parse_fmtp(ffmpeg_private *ff) 
     364{ 
     365    pjmedia_dir dir; 
     366    pj_status_t status; 
     367 
     368    dir = ff->param.dir; 
     369 
     370    if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 
     371        pjmedia_vid_codec_param param_ref; 
     372        pjmedia_codec_fmtp *fmtp_rem, *fmtp_ref; 
     373        itu_cap local_cap; 
     374        pjmedia_rect_size size = {0}; 
     375        unsigned mpi = 0; 
     376        pj_bool_t got_good_res = PJ_FALSE; 
     377        pj_bool_t has_prefered_res = PJ_FALSE; 
     378        unsigned i, j; 
     379 
     380        fmtp_rem = &ff->param.enc_fmtp; 
     381        dir &= ~PJMEDIA_DIR_ENCODING; 
     382 
     383        /* Get default fmtp setting as the reference for local capabilities */ 
     384        status = pjmedia_vid_codec_mgr_get_default_param( 
     385                        ffmpeg_factory.mgr, &ff->desc->info, &param_ref); 
     386        fmtp_ref = (status==PJ_SUCCESS)? &param_ref.enc_fmtp : fmtp_rem; 
     387 
     388        /* Load default local capabilities */ 
     389        status = load_itu_cap(fmtp_ref, &local_cap); 
     390        pj_assert(status == PJ_SUCCESS); 
     391 
     392        /* Negotiate resolution and MPI */ 
     393        for (i=0; i<fmtp_rem->cnt && !got_good_res; ++i) 
     394        { 
     395            for (j=0; j<PJ_ARRAY_SIZE(itu_res_def) && !got_good_res; ++j) 
     396            { 
     397                if (pj_stricmp(&fmtp_rem->param[i].name, &itu_res_def[j].name)) 
     398                    continue; 
     399 
     400                has_prefered_res = PJ_TRUE; 
     401                if (j == ITU_RES_CUSTOM) { 
     402                    unsigned score; 
     403 
     404                    if (parse_fmtp_itu_custom_res(&fmtp_rem->param[i].val,  
     405                                                  &size, &mpi) != PJ_SUCCESS) 
     406                    { 
     407                        /* Invalid custom resolution format, skip this  
     408                         * custom resolution 
     409                         */ 
     410                        break; 
     411                    } 
     412 
     413                    score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 
     414                    if (score <= local_cap.custom_res_max_score) 
     415                        got_good_res = PJ_TRUE; 
     416                } else { 
     417                    mpi = pj_strtoul(&fmtp_rem->param[i].val); 
     418                    if (mpi>=1 && mpi<=32 && mpi>=local_cap.lowest_mpi[j]) { 
     419                        got_good_res = PJ_TRUE; 
     420                        size = itu_res_def[j].size; 
     421                    } 
     422                } 
     423            } 
     424        } 
     425 
     426        if (has_prefered_res) { 
     427            if (got_good_res) { 
     428                pjmedia_video_format_detail *vfd; 
     429 
     430                /* Apply this size & MPI */ 
     431                vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, 
     432                                                             PJ_TRUE); 
     433                vfd->size = size; 
     434                vfd->fps.num = 30000; 
     435                vfd->fps.denum = 1001 * mpi; 
     436                got_good_res = PJ_TRUE; 
     437 
     438                PJ_TODO(NOTIFY_APP_ABOUT_THIS_NEW_ENCODING_FORMAT); 
     439            } else { 
     440                return PJ_EUNKNOWN; 
     441            } 
     442        } 
     443    } 
     444 
     445    return PJ_SUCCESS; 
     446} 
     447 
     448 
     449 
     450static const ffmpeg_codec_desc* find_codec_info( 
     451                        const pjmedia_vid_codec_info *info) 
     452{ 
     453    int i; 
     454 
     455    for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) { 
     456        ffmpeg_codec_desc *desc = &codec_desc[i]; 
     457 
     458        if (desc->enabled && 
     459            (desc->info.fmt_id == info->fmt_id) && 
     460            ((desc->info.dir & info->dir) == info->dir) && 
     461            pj_stricmp(&desc->info.encoding_name, &info->encoding_name)==0) 
     462        { 
     463            return desc; 
     464        } 
     465    } 
     466 
     467    return NULL; 
     468} 
     469 
     470 
     471static int find_codec_info_idx_by_fmt_id(pjmedia_format_id fmt_id) 
     472{ 
     473    int i; 
     474    for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) { 
     475        if (codec_desc[i].info.fmt_id == fmt_id) 
     476            return i; 
     477    } 
     478 
     479    return -1; 
     480} 
    155481 
    156482 
     
    163489    pj_pool_t *pool; 
    164490    AVCodec *c; 
    165     enum CodecID last_codec_id = CODEC_ID_NONE; 
    166491    pj_status_t status; 
    167492 
     
    179504    ffmpeg_factory.mgr = mgr; 
    180505    ffmpeg_factory.pf = pf; 
    181     pj_list_init(&ffmpeg_factory.codecs); 
    182506 
    183507    pool = pj_pool_create(pf, "ffmpeg codec factory", 256, 256, NULL); 
     
    197521    for (c=av_codec_next(NULL); c; c=av_codec_next(c))  
    198522    { 
    199         ffmpeg_codec_info *ci; 
     523        ffmpeg_codec_desc *desc; 
     524        pjmedia_format_id fmt_id; 
     525        int codec_info_idx; 
    200526         
    201527        if (c->type != CODEC_TYPE_VIDEO) 
     
    203529 
    204530        /* Video encoder and decoder are usually implemented in separate 
    205          * AVCodec instances. 
     531         * AVCodec instances. While the codec attributes (e.g: raw formats, 
     532         * supported fps) are in the encoder. 
    206533         */ 
    207534 
    208         if (c->id == last_codec_id) { 
    209             /* This codec usually be the decoder, and not as much info as in 
    210              * encoder can be fetched here. 
    211              */ 
    212             pj_assert(!pj_list_empty(&ffmpeg_factory.codecs)); 
    213             ci = ffmpeg_factory.codecs.prev; 
    214             pj_assert(ci->info.dir != PJMEDIA_DIR_ENCODING_DECODING); 
    215             pj_assert(!ci->dec || !ci->enc); 
    216         } else { 
    217             pjmedia_format_id enc_fmt_id; 
    218             pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT]; 
    219             unsigned raw_fmt_cnt = 0; 
    220             unsigned raw_fmt_cnt_should_be = 0; 
    221  
    222             /* Get encoded format id */ 
    223             status = CodecID_to_pjmedia_format_id(c->id, &enc_fmt_id); 
    224             if (status != PJ_SUCCESS) { 
    225                 //PJ_LOG(5, (THIS_FILE, "Unrecognized ffmpeg codec id %d, " 
    226                 //                      "codec [%s/%s] ignored", 
    227                 //                      c->id, c->name, c->long_name)); 
    228                 //enc_fmt_id = PJMEDIA_FORMAT_FFMPEG_UNKNOWN; 
    229  
    230                 /* Skip unrecognized encoding format ID */ 
    231                 continue; 
    232             } 
    233  
    234             /* Get raw/decoded format ids */ 
    235             if (c->pix_fmts) { 
    236                 const enum PixelFormat *p = c->pix_fmts; 
    237                 for(;(p && *p != -1) && 
    238                      (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT); 
    239                      ++p) 
    240                 { 
    241                     pjmedia_format_id fmt_id; 
    242  
    243                     raw_fmt_cnt_should_be++; 
    244                     status = PixelFormat_to_pjmedia_format_id(*p, &fmt_id); 
    245                     if (status != PJ_SUCCESS) { 
    246                         PJ_LOG(6, (THIS_FILE, "Unrecognized ffmpeg pixel " 
    247                                    "format %d", *p)); 
    248                         continue; 
    249                     } 
    250                     raw_fmt[raw_fmt_cnt++] = fmt_id; 
    251                 } 
    252             } else { 
    253                 /* Unknown raw format, ignore this codec? */ 
    254                 continue; 
    255             } 
    256  
    257             if (raw_fmt_cnt < raw_fmt_cnt_should_be) { 
    258                 PJ_LOG(6, (THIS_FILE, "Codec [%s/%s] have %d raw formats, " 
    259                                       "recognized only %d raw formats", 
    260                                       c->name, c->long_name, 
    261                                       raw_fmt_cnt_should_be, raw_fmt_cnt)); 
    262             } 
    263             if (raw_fmt_cnt == 0) { 
    264                 PJ_LOG(5, (THIS_FILE, "No recognized raw format " 
    265                                       "for codec [%s/%s], codec ignored", 
    266                                       c->name, c->long_name)); 
    267                 /* Comment this to see all ffmpeg codecs */ 
    268                 continue; 
    269             } 
    270  
    271             ci = PJ_POOL_ZALLOC_T(pool, ffmpeg_codec_info); 
    272             ci->info.fmt_id = enc_fmt_id; 
    273             pj_cstr(&ci->info.encoding_name, c->name); 
    274             ci->info.clock_rate = 90000; 
    275             ci->info.dec_fmt_id_cnt = raw_fmt_cnt; 
    276             pj_memcpy(ci->info.dec_fmt_id, raw_fmt,  
    277                       sizeof(raw_fmt[0])*raw_fmt_cnt); 
    278  
    279             switch (enc_fmt_id) { 
    280                 case PJMEDIA_FORMAT_H263: 
    281                     ci->info.pt = PJMEDIA_RTP_PT_H263; 
    282                     break; 
    283                 case PJMEDIA_FORMAT_H261: 
    284                     ci->info.pt = PJMEDIA_RTP_PT_H261; 
    285                     break; 
    286                 default: 
    287                     break; 
    288             } 
    289  
    290             if (c->supported_framerates) { 
    291                 const AVRational *fr = c->supported_framerates; 
    292                 while ((fr->num != 0 || fr->den != 0) &&  
    293                        ci->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT) 
    294                 { 
    295                     ci->info.fps[ci->info.fps_cnt].num = fr->num; 
    296                     ci->info.fps[ci->info.fps_cnt].denum = fr->den; 
    297                     ++ci->info.fps_cnt; 
    298                     ++fr; 
    299                 } 
    300             } 
    301  
    302             pj_list_push_back(&ffmpeg_factory.codecs, ci); 
     535        status = CodecID_to_pjmedia_format_id(c->id, &fmt_id); 
     536        /* Skip if format ID is unknown */ 
     537        if (status != PJ_SUCCESS) 
     538            continue; 
     539 
     540        codec_info_idx = find_codec_info_idx_by_fmt_id(fmt_id); 
     541        /* Skip if codec is unwanted by this wrapper (not listed in  
     542         * the codec info array) 
     543         */ 
     544        if (codec_info_idx < 0) 
     545            continue; 
     546 
     547        desc = &codec_desc[codec_info_idx]; 
     548 
     549        /* Skip duplicated codec implementation */ 
     550        if ((c->encode && (desc->info.dir & PJMEDIA_DIR_ENCODING)) || 
     551            (c->decode && (desc->info.dir & PJMEDIA_DIR_DECODING))) 
     552        { 
     553            continue; 
     554        } 
     555 
     556        /* Get raw/decoded format ids in the encoder */ 
     557        if (c->pix_fmts && c->encode) { 
     558            pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT]; 
     559            unsigned raw_fmt_cnt = 0; 
     560            unsigned raw_fmt_cnt_should_be = 0; 
     561            const enum PixelFormat *p = c->pix_fmts; 
     562 
     563            for(;(p && *p != -1) && 
     564                 (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT); 
     565                 ++p) 
     566            { 
     567                pjmedia_format_id fmt_id; 
     568 
     569                raw_fmt_cnt_should_be++; 
     570                status = PixelFormat_to_pjmedia_format_id(*p, &fmt_id); 
     571                if (status != PJ_SUCCESS) { 
     572                    PJ_LOG(6, (THIS_FILE, "Unrecognized ffmpeg pixel " 
     573                               "format %d", *p)); 
     574                    continue; 
     575                } 
     576                raw_fmt[raw_fmt_cnt++] = fmt_id; 
     577            } 
     578 
     579            if (raw_fmt_cnt == 0) { 
     580                PJ_LOG(5, (THIS_FILE, "No recognized raw format " 
     581                                      "for codec [%s/%s], codec ignored", 
     582                                      c->name, c->long_name)); 
     583                /* Skip this encoder */ 
     584                continue; 
     585            } 
     586 
     587            if (raw_fmt_cnt < raw_fmt_cnt_should_be) { 
     588                PJ_LOG(6, (THIS_FILE, "Codec [%s/%s] have %d raw formats, " 
     589                                      "recognized only %d raw formats", 
     590                                      c->name, c->long_name, 
     591                                      raw_fmt_cnt_should_be, raw_fmt_cnt)); 
     592            } 
     593 
     594            desc->info.dec_fmt_id_cnt = raw_fmt_cnt; 
     595            pj_memcpy(desc->info.dec_fmt_id, raw_fmt,  
     596                      sizeof(raw_fmt[0])*raw_fmt_cnt); 
     597        } 
     598 
     599        /* Get supported framerates */ 
     600        if (c->supported_framerates) { 
     601            const AVRational *fr = c->supported_framerates; 
     602            while ((fr->num != 0 || fr->den != 0) &&  
     603                   desc->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT) 
     604            { 
     605                desc->info.fps[desc->info.fps_cnt].num = fr->num; 
     606                desc->info.fps[desc->info.fps_cnt].denum = fr->den; 
     607                ++desc->info.fps_cnt; 
     608                ++fr; 
     609            } 
     610        } 
     611 
     612        /* Get ffmpeg encoder instance */ 
     613        if (c->encode && !desc->enc) { 
     614            desc->info.dir |= PJMEDIA_DIR_ENCODING; 
     615            desc->enc = c; 
    303616        } 
    304  
    305         if (c->encode) { 
    306             ci->info.dir |= PJMEDIA_DIR_ENCODING; 
    307             ci->enc = c; 
     617         
     618        /* Get ffmpeg decoder instance */ 
     619        if (c->decode && !desc->dec) { 
     620            desc->info.dir |= PJMEDIA_DIR_DECODING; 
     621            desc->dec = c; 
    308622        } 
    309         if (c->decode) { 
    310             ci->info.dir |= PJMEDIA_DIR_DECODING; 
    311             ci->dec = c; 
    312         } 
    313  
    314         last_codec_id = c->id; 
     623 
     624        /* Enable this codec when any ffmpeg codec instance are recognized 
     625         * and the supported raw formats info has been collected. 
     626         */ 
     627        if ((desc->dec || desc->enc) && desc->info.dec_fmt_id_cnt) 
     628        { 
     629            desc->enabled = PJ_TRUE; 
     630        } 
     631 
     632        /* Normalize default value of clock rate */ 
     633        if (desc->info.clock_rate == 0) 
     634            desc->info.clock_rate = 90000; 
    315635    } 
    316636 
     
    360680 
    361681 
    362 static ffmpeg_codec_info* find_codec(const pjmedia_vid_codec_info *info) 
    363 { 
    364     ffmpeg_codec_info *ci = ffmpeg_factory.codecs.next; 
    365  
    366     pj_mutex_lock(ffmpeg_factory.mutex); 
    367  
    368     while (ci != &ffmpeg_factory.codecs) { 
    369         if ((ci->info.fmt_id == info->fmt_id) && 
    370             ((ci->info.dir & info->dir) == info->dir) && 
    371             pj_stricmp(&ci->info.encoding_name, &info->encoding_name)==0) 
    372         { 
    373             pj_mutex_unlock(ffmpeg_factory.mutex); 
    374             return ci; 
    375         } 
    376         ci = ci->next; 
    377     } 
    378  
    379     pj_mutex_unlock(ffmpeg_factory.mutex); 
    380  
    381     return NULL; 
    382 } 
    383  
    384  
    385682/*  
    386683 * Check if factory can allocate the specified codec.  
     
    389686                                      const pjmedia_vid_codec_info *info ) 
    390687{ 
    391     ffmpeg_codec_info *ci; 
     688    const ffmpeg_codec_desc *desc; 
    392689 
    393690    PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL); 
    394691    PJ_ASSERT_RETURN(info, PJ_EINVAL); 
    395692 
    396     ci = find_codec(info); 
    397     if (!ci) { 
     693    desc = find_codec_info(info); 
     694    if (!desc) { 
    398695        return PJMEDIA_CODEC_EUNSUP; 
    399696    } 
     
    409706                                        pjmedia_vid_codec_param *attr ) 
    410707{ 
    411     ffmpeg_codec_info *ci; 
     708    const ffmpeg_codec_desc *desc; 
    412709 
    413710    PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL); 
    414711    PJ_ASSERT_RETURN(info && attr, PJ_EINVAL); 
    415712 
    416     ci = find_codec(info); 
    417     if (!ci) { 
     713    desc = find_codec_info(info); 
     714    if (!desc) { 
    418715        return PJMEDIA_CODEC_EUNSUP; 
    419716    } 
    420717 
    421718    pj_bzero(attr, sizeof(pjmedia_vid_codec_param)); 
    422     attr->dir = ci->info.dir; 
    423     attr->pt = info->pt; 
    424     pjmedia_format_init_video(&attr->enc_fmt, ci->info.fmt_id, 
    425                               352, 288, 25, 1); 
    426     pjmedia_format_init_video(&attr->dec_fmt, ci->info.dec_fmt_id[0], 
    427                               352, 288, 25, 1); 
     719 
     720    /* Direction */ 
     721    attr->dir = desc->info.dir; 
     722 
     723    /* Encoded format */ 
     724    pjmedia_format_init_video(&attr->enc_fmt, desc->info.fmt_id, 
     725                              352, 288, 30000, 1001); 
     726 
     727    /* Decoded format */ 
     728    pjmedia_format_init_video(&attr->dec_fmt, desc->info.dec_fmt_id[0], 
     729                              352, 288, 30000, 1001); 
     730 
     731    /* Decoding fmtp */ 
     732    attr->dec_fmtp = desc->dec_fmtp; 
    428733 
    429734    return PJ_SUCCESS; 
     
    437742                                       pjmedia_vid_codec_info codecs[]) 
    438743{ 
    439     ffmpeg_codec_info *ci; 
    440     unsigned max; 
     744    unsigned i; 
    441745 
    442746    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL); 
    443747    PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL); 
    444748 
    445     max = *count; 
    446     *count = 0; 
    447     ci = ffmpeg_factory.codecs.next; 
    448  
    449     pj_mutex_lock(ffmpeg_factory.mutex); 
    450     while (*count < max && ci != &ffmpeg_factory.codecs) { 
    451         pj_memcpy(&codecs[*count], &ci->info, sizeof(pjmedia_vid_codec_info)); 
    452         *count = *count + 1; 
    453         ci = ci->next; 
    454     } 
    455     pj_mutex_unlock(ffmpeg_factory.mutex); 
     749    *count = PJ_MIN(*count, PJ_ARRAY_SIZE(codec_desc)); 
     750 
     751    for (i=0; i<*count; ++i) { 
     752        pj_memcpy(&codecs[i], &codec_desc[i].info,  
     753                  sizeof(pjmedia_vid_codec_info)); 
     754    } 
    456755 
    457756    return PJ_SUCCESS; 
     
    466765{ 
    467766    ffmpeg_private *ff; 
    468     ffmpeg_codec_info *ci; 
     767    const ffmpeg_codec_desc *desc; 
    469768    pjmedia_vid_codec *codec; 
    470769    pj_pool_t *pool = NULL; 
     
    474773    PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL); 
    475774 
    476     ci = find_codec(info); 
    477     if (!ci) { 
     775    desc = find_codec_info(info); 
     776    if (!desc) { 
    478777        return PJMEDIA_CODEC_EUNSUP; 
    479778    } 
     
    495794    codec->codec_data = ff; 
    496795    ff->pool = pool; 
    497     ff->enc = ci->enc; 
    498     ff->dec = ci->dec; 
     796    ff->enc = desc->enc; 
     797    ff->dec = desc->dec; 
     798    ff->desc = desc; 
    499799 
    500800    *p_codec = codec; 
     
    551851} 
    552852 
    553 /* 
    554 static enum PixelFormat ffdec_nego_format(struct AVCodecContext *s,  
     853static enum PixelFormat dec_get_format(struct AVCodecContext *s,  
    555854                                          const enum PixelFormat * fmt) 
    556855{ 
    557     enum PixelFormat pix_fmt; 
    558  
    559     PJ_UNUSED_ARG(s); 
    560     PJ_UNUSED_ARG(fmt); 
    561  
    562     pjmedia_format_id_to_PixelFormat(PJMEDIA_FORMAT_BGRA, &pix_fmt); 
    563     return pix_fmt; 
    564 } 
    565  
    566 static void enc_got_payload(struct AVCodecContext *avctx, 
    567                             void *data, int size, int mb_nb); 
    568 */ 
     856    ffmpeg_private *ff = (ffmpeg_private*)s->opaque; 
     857    enum PixelFormat def_fmt = *fmt; 
     858 
     859    while (*fmt != -1) { 
     860        if (*fmt == ff->expected_dec_fmt) 
     861            return *fmt; 
     862        ++fmt; 
     863    } 
     864 
     865    pj_assert(!"Inconsistency in supported formats"); 
     866    return def_fmt; 
     867} 
    569868 
    570869 
     
    574873    enum PixelFormat pix_fmt; 
    575874    pj_status_t status; 
     875    pjmedia_video_format_detail *vfd; 
    576876 
    577877    status = pjmedia_format_id_to_PixelFormat(ff->param.dec_fmt.id, 
     
    579879    if (status != PJ_SUCCESS) 
    580880        return status; 
     881 
     882    vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt,  
     883                                                 PJ_TRUE); 
     884    ff->expected_dec_fmt = pix_fmt; 
    581885 
    582886    while (((ff->param.dir & PJMEDIA_DIR_ENCODING) && ff->enc_ctx == NULL) || 
     
    595899        } 
    596900 
     901        /* Init ffmpeg codec context */ 
    597902        ctx = avcodec_alloc_context(); 
    598903 
    599904        /* Common attributes */ 
    600905        ctx->pix_fmt = pix_fmt; 
    601         ctx->width = ff->param.enc_fmt.det.vid.size.w; 
    602         ctx->height = ff->param.enc_fmt.det.vid.size.h; 
    603906        ctx->workaround_bugs = FF_BUG_AUTODETECT; 
    604907        ctx->opaque = ff; 
     
    608911 
    609912            /* Encoding only attributes */ 
    610             ctx->time_base.num = ff->param.enc_fmt.det.vid.fps.denum; 
    611             ctx->time_base.den = ff->param.enc_fmt.det.vid.fps.num; 
    612             if (ff->param.enc_fmt.det.vid.avg_bps) 
    613                 ctx->bit_rate = ff->param.enc_fmt.det.vid.avg_bps; 
    614             if (ff->param.enc_fmt.det.vid.max_bps) 
    615                 ctx->rc_max_rate = ff->param.enc_fmt.det.vid.max_bps; 
    616 #if 0 
    617             if (ff->param.enc_mtu) { 
    618                 //ctx->rtp_payload_size = ff->param.enc_mtu; 
    619                 //ctx->rtp_callback = &enc_got_payload; 
    620  
    621                 /* Allocate frame array for RTP payload packing */ 
    622                 if (ff->param.enc_fmt.det.vid.max_bps) 
    623                     ff->pack_frm_max_cnt = ff->param.enc_fmt.det.vid.max_bps / 
    624                                            ff->param.enc_mtu + 1; 
    625                 else 
    626                     ff->pack_frm_max_cnt = 32; 
    627  
    628                 ff->pack_frms = (pjmedia_frame*) 
    629                                 pj_pool_calloc(ff->pool, ff->pack_frm_max_cnt, 
    630                                                sizeof(ff->pack_frms[0])); 
    631             } 
    632 #endif 
    633  
    634             /* For encoder, should be better to be strict to the standards */ 
     913            ctx->width = vfd->size.w; 
     914            ctx->height = vfd->size.h; 
     915            ctx->time_base.num = vfd->fps.denum; 
     916            ctx->time_base.den = vfd->fps.num; 
     917            if (vfd->avg_bps) 
     918                ctx->bit_rate = vfd->avg_bps; 
     919            if (vfd->max_bps) 
     920                ctx->rc_max_rate = vfd->max_bps; 
     921 
     922            /* For encoder, should be better to be strict to the standards */ 
    635923            ctx->strict_std_compliance = FF_COMPLIANCE_STRICT; 
    636924        } 
     925 
    637926        if (dir & PJMEDIA_DIR_DECODING) { 
    638927            codec = ff->dec; 
    639928 
    640929            /* Decoding only attributes */ 
    641             ctx->coded_width = ctx->width; 
    642             ctx->coded_height = ctx->height; 
     930            // this setting will be automatically fetched from the bitstream. 
     931            //ctx->coded_width = ff->param.dec_fmt.det.vid.size.w; 
     932            //ctx->coded_height = ff->param.dec_fmt.det.vid.size.h; 
    643933 
    644934            /* For decoder, be more flexible */ 
    645             if (ff->param.dir!=PJMEDIA_DIR_ENCODING_DECODING || ff->enc!=ff->dec) 
     935            if (ff->param.dir!=PJMEDIA_DIR_ENCODING_DECODING ||  
     936                ff->enc!=ff->dec) 
     937            { 
    646938                ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; 
    647  
    648             //ctx->get_format = &ffdec_nego_format; 
     939            } 
     940 
     941            ctx->get_format = &dec_get_format; 
    649942        } 
    650943 
     
    680973    ff = (ffmpeg_private*)codec->codec_data; 
    681974 
    682     ff->vfi = pjmedia_get_video_format_info(NULL, attr->dec_fmt.id); 
    683     if (!ff->vfi) { 
    684         status = PJ_EINVAL; 
    685         goto on_error; 
    686     } 
    687  
    688     pj_bzero(&ff->vafp, sizeof(ff->vafp)); 
    689     ff->vafp.size = attr->dec_fmt.det.vid.size; 
    690     ff->vafp.buffer = 0; 
    691     status = (*ff->vfi->apply_fmt)(ff->vfi, &ff->vafp); 
    692     if (status != PJ_SUCCESS) { 
    693         goto on_error; 
    694     } 
    695  
    696975    pj_memcpy(&ff->param, attr, sizeof(*attr)); 
    697976 
     977    /* Apply SDP fmtp attribute */ 
     978    if (ff->desc->parse_fmtp) { 
     979        status = (*ff->desc->parse_fmtp)(ff); 
     980        if (status != PJ_SUCCESS) 
     981            goto on_error; 
     982    } 
     983 
     984    /* Open the codec */ 
    698985    ff_mutex = ((struct ffmpeg_factory*)codec->factory)->mutex; 
    699986    status = open_ffmpeg_codec(ff, ff_mutex); 
     
    701988        goto on_error; 
    702989 
     990    /* Init format info and apply-param of decoder */ 
     991    ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id); 
     992    if (!ff->dec_vfi) { 
     993        status = PJ_EINVAL; 
     994        goto on_error; 
     995    } 
     996    pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp)); 
     997    ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size; 
     998    ff->dec_vafp.buffer = NULL; 
     999    status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp); 
     1000    if (status != PJ_SUCCESS) { 
     1001        goto on_error; 
     1002    } 
     1003 
     1004    /* Init format info and apply-param of encoder */ 
     1005    ff->enc_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id); 
     1006    if (!ff->enc_vfi) { 
     1007        status = PJ_EINVAL; 
     1008        goto on_error; 
     1009    } 
     1010    pj_bzero(&ff->enc_vafp, sizeof(ff->enc_vafp)); 
     1011    ff->enc_vafp.size = ff->param.enc_fmt.det.vid.size; 
     1012    ff->enc_vafp.buffer = NULL; 
     1013    status = (*ff->enc_vfi->apply_fmt)(ff->enc_vfi, &ff->enc_vafp); 
     1014    if (status != PJ_SUCCESS) { 
     1015        goto on_error; 
     1016    } 
     1017 
     1018    /* Update codec attributes, e.g: encoding format may be changed by 
     1019     * SDP fmtp negotiation. 
     1020     */ 
     1021    pj_memcpy(attr, &ff->param, sizeof(*attr)); 
     1022 
    7031023    return PJ_SUCCESS; 
    7041024 
     
    7291049        av_free(ff->dec_ctx); 
    7301050    } 
    731     if (ff->dec_parser_ctx) { 
    732         av_parser_close(ff->dec_parser_ctx); 
    733  
     1051    if (ff->sws_ctx) { 
     1052        sws_freeContext(ff->sws_ctx); 
    7341053    } 
    7351054    ff->enc_ctx = NULL; 
    7361055    ff->dec_ctx = NULL; 
    737     ff->dec_parser_ctx = NULL; 
     1056    ff->sws_ctx = NULL; 
    7381057    pj_mutex_unlock(ff_mutex); 
    7391058 
     
    7461065 */ 
    7471066static pj_status_t  ffmpeg_codec_modify( pjmedia_vid_codec *codec,  
    748                                          const pjmedia_vid_codec_param *attr ) 
     1067                                         const pjmedia_vid_codec_param *attr) 
    7491068{ 
    7501069    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
     
    7551074    return PJ_ENOTSUP; 
    7561075} 
     1076 
     1077static pj_status_t  ffmpeg_codec_get_param(pjmedia_vid_codec *codec, 
     1078                                           pjmedia_vid_codec_param *param) 
     1079{ 
     1080    ffmpeg_private *ff; 
     1081 
     1082    PJ_ASSERT_RETURN(codec && param, PJ_EINVAL); 
     1083 
     1084    ff = (ffmpeg_private*)codec->codec_data; 
     1085    pj_memcpy(param, &ff->param, sizeof(*param)); 
     1086 
     1087    return PJ_SUCCESS; 
     1088} 
     1089 
    7571090 
    7581091static pj_status_t  ffmpeg_packetize ( pjmedia_vid_codec *codec, 
     
    7651098    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
    7661099 
    767     switch (ff->param.enc_fmt.id) { 
    768         case PJMEDIA_FORMAT_H263: 
    769             return pjmedia_h263_packetize(buf, buf_len, pos, 
    770                                           ff->param.enc_mtu, payload, 
    771                                           payload_len); 
    772             break; 
    773         default: 
    774             return PJ_ENOTSUP; 
    775     } 
     1100    if (ff->desc->packetize) { 
     1101        return (*ff->desc->packetize)(buf, buf_len, pos, 
     1102                                      ff->param.enc_mtu, payload, 
     1103                                      payload_len); 
     1104    } 
     1105 
     1106    return PJ_ENOTSUP; 
    7761107} 
    7771108 
     
    7841115    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
    7851116 
    786     switch (ff->param.enc_fmt.id) { 
    787         case PJMEDIA_FORMAT_H263: 
    788             return pjmedia_h263_unpacketize(payload, payload_len, 
    789                                             buf, buf_len); 
    790             break; 
    791         default: 
    792             return PJ_ENOTSUP; 
    793     } 
    794 } 
    795  
    796 #if 0 
    797 /* 
    798  * Pack encoded frame to RTP payload frames. 
    799  */ 
    800 static pj_status_t  ffmpeg_codec_pack ( pjmedia_vid_codec *codec, 
    801                                         const pjmedia_frame *enc_frame, 
    802                                         unsigned *frame_cnt, 
    803                                         pjmedia_frame frames[]) 
    804 { 
    805     ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
    806     unsigned i; 
    807  
    808     /* Can only work when encoding MTU is set */ 
    809     PJ_ASSERT_RETURN(ff->param.enc_mtu, PJ_EINVALIDOP); 
    810  
    811     /* Validate available payload number */ 
    812     PJ_ASSERT_RETURN(ff->pack_frm_cnt <= *frame_cnt, PJ_EINVALIDOP); 
    813  
    814     /* Validate encoded bitstream */ 
    815     PJ_ASSERT_RETURN(ff->pack_frm_cnt==0 ||  
    816                      ff->pack_frms[0].buf == enc_frame->buf, 
    817                      PJ_EINVAL); 
    818  
    819     /* Return the payloads */ 
    820     *frame_cnt = ff->pack_frm_cnt; 
    821     for (i = 0; i < *frame_cnt; ++i) 
    822         frames[i] = ff->pack_frms[i]; 
    823  
    824     return PJ_SUCCESS; 
    825 } 
    826  
    827 /* 
    828  * Get frames in the packet. 
    829  */ 
    830 static pj_status_t  ffmpeg_codec_parse( pjmedia_vid_codec *codec, 
    831                                         void *pkt, 
    832                                         pj_size_t pkt_size, 
    833                                         const pj_timestamp *ts, 
    834                                         pjmedia_frame *frame) 
    835 { 
    836     ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
    837     pj_uint8_t *buf = frame->buf; 
    838     int buf_size = frame->size; 
    839     int processed; 
    840  
    841  
    842     if (!ff->dec_parser_ctx) { 
    843         ff->dec_parser_ctx = av_parser_init(ff->dec->id); 
    844         if (!ff->dec_parser_ctx) 
    845             return PJ_ENOTSUP; 
    846     } 
    847  
    848 #if LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72 
    849     processed = av_parser_parse2(ff->dec_parser_ctx, ff->dec_ctx,  
    850                                  &buf, &buf_size, (uint8_t*)pkt, pkt_size, 
    851                                  ts->u64, ts->u64, AV_NOPTS_VALUE); 
    852 #else 
    853     processed = av_parser_parse (ff->dec_parser_ctx, ff->dec_ctx,  
    854                                  &buf, &buf_size, (uint8_t*)pkt, pkt_size, 
    855                                  ts->u64, ts->u64); 
    856 #endif 
    857  
    858     if (buf_size) { 
    859         frame->timestamp = *ts; 
    860         frame->size = buf_size; 
    861         return PJ_SUCCESS; 
    862     } 
    863  
    864     return PJ_EPENDING; 
    865 } 
    866  
    867 static void enc_got_payload(struct AVCodecContext *avctx, 
    868                             void *data, int size, int mb_nb) 
    869 { 
    870     ffmpeg_private *ff = (ffmpeg_private*) avctx->opaque; 
    871     pjmedia_frame *payload; 
    872  
    873     pj_assert(ff->pack_frm_cnt < ff->pack_frm_max_cnt); 
    874     payload = &ff->pack_frms[ff->pack_frm_cnt++]; 
    875     payload->buf = data; 
    876     payload->size = size; 
    877     payload->bit_info = mb_nb; 
    878 } 
    879  
    880 #endif 
     1117    if (ff->desc->unpacketize) { 
     1118        return (*ff->desc->unpacketize)(payload, payload_len, 
     1119                                        buf, buf_len); 
     1120    } 
     1121     
     1122    return PJ_ENOTSUP; 
     1123} 
    8811124 
    8821125 
     
    8851128 */ 
    8861129static pj_status_t ffmpeg_codec_encode( pjmedia_vid_codec *codec,  
    887                                         const struct pjmedia_frame *input, 
     1130                                        const pjmedia_frame *input, 
    8881131                                        unsigned output_buf_len,  
    889                                         struct pjmedia_frame *output) 
     1132                                        pjmedia_frame *output) 
    8901133{ 
    8911134    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
     
    9001143    PJ_ASSERT_RETURN(ff->enc_ctx, PJ_EINVALIDOP); 
    9011144 
    902     /* 
    903     ff->pack_frm_cnt = 0; 
    904     */ 
    9051145    avcodec_get_frame_defaults(&avframe); 
    9061146     
    907     for (i = 0; i < ff->vfi->plane_cnt; ++i) { 
     1147    for (i = 0; i < ff->enc_vfi->plane_cnt; ++i) { 
    9081148        avframe.data[i] = p; 
    909         avframe.linesize[i] = ff->vafp.strides[i]; 
    910         p += ff->vafp.plane_bytes[i]; 
     1149        avframe.linesize[i] = ff->enc_vafp.strides[i]; 
     1150        p += ff->enc_vafp.plane_bytes[i]; 
    9111151    } 
    9121152 
     
    9461186 */ 
    9471187static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec,  
    948                                         const struct pjmedia_frame *input, 
     1188                                        const pjmedia_frame *input, 
    9491189                                        unsigned output_buf_len,  
    950                                         struct pjmedia_frame *output) 
     1190                                        pjmedia_frame *output) 
    9511191{ 
    9521192    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
     
    9581198    PJ_ASSERT_RETURN(ff->dec_ctx, PJ_EINVALIDOP); 
    9591199 
    960     PJ_UNUSED_ARG(output_buf_len); 
     1200    /* Validate output buffer size */ 
     1201    PJ_ASSERT_RETURN(ff->dec_vafp.framebytes <= output_buf_len, PJ_ETOOSMALL); 
    9611202 
    9621203    /* Init frame to receive the decoded data, the ffmpeg codec context will 
     
    9791220     */ 
    9801221    pj_bzero(avpacket.data+avpacket.size, FF_INPUT_BUFFER_PADDING_SIZE); 
     1222 
     1223    output->bit_info = 0; 
    9811224 
    9821225#if LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72 
     
    9971240        return PJ_EUNKNOWN; 
    9981241    } else if (got_picture) { 
    999         pjmedia_video_apply_fmt_param *vafp = (pjmedia_video_apply_fmt_param*) 
    1000                                               &ff->vafp; 
     1242        pjmedia_video_apply_fmt_param *vafp = &ff->dec_vafp; 
    10011243        pj_uint8_t *q = (pj_uint8_t*)output->buf; 
    1002         unsigned i; 
    1003  
    1004         /* Get the decoded data */ 
    1005         for (i = 0; i < ff->vfi->plane_cnt; ++i) { 
    1006             pj_uint8_t *p = avframe.data[i]; 
    1007  
    1008             /* The decoded data may contain padding */ 
    1009             if (avframe.linesize[i]==vafp->strides[i]) { 
    1010                 /* No padding, copy the whole plane */ 
    1011                 pj_memcpy(q, p, vafp->plane_bytes[i]); 
    1012                 q += vafp->plane_bytes[i]; 
    1013             } else { 
    1014                 /* Padding exists, copy line by line */ 
    1015                 pj_uint8_t *q_end; 
    1016                  
    1017                 q_end = q+vafp->plane_bytes[i]; 
    1018                 while(q < q_end) { 
    1019                     pj_memcpy(q, p, vafp->strides[i]); 
    1020                     q += vafp->strides[i]; 
    1021                     p += avframe.linesize[i]; 
    1022                 } 
    1023             } 
    1024         } 
     1244        unsigned i; 
     1245 
     1246        /* Decoder output format is set by libavcodec, in case it is different 
     1247         * to the configured param. 
     1248         */ 
     1249        if (ff->dec_ctx->pix_fmt != ff->expected_dec_fmt || 
     1250            ff->dec_ctx->coded_width != (int)vafp->size.w || 
     1251            ff->dec_ctx->coded_height != (int)vafp->size.h) 
     1252        { 
     1253#if 0        
     1254            // it should not be the codec responsibility to do resizing 
     1255            pj_uint8_t *data[PJMEDIA_MAX_VIDEO_PLANES] = {0}; 
     1256            unsigned i; 
     1257            int h; 
     1258 
     1259            if (!ff->sws_ctx) { 
     1260                pj_assert(sws_isSupportedInput(ff->dec_ctx->pix_fmt) > 0); 
     1261                pj_assert(sws_isSupportedOutput(ff->expected_dec_fmt) > 0); 
     1262                ff->sws_ctx = sws_getContext(ff->dec_ctx->coded_width, 
     1263                                             ff->dec_ctx->coded_height, 
     1264                                             ff->dec_ctx->pix_fmt, 
     1265                                             vafp->size.w, vafp->size.h, 
     1266                                             ff->expected_dec_fmt, 
     1267                                             SWS_BILINEAR | SWS_PRINT_INFO, 
     1268                                             NULL, NULL, NULL); 
     1269                if (ff->sws_ctx == NULL) { 
     1270                    return PJ_EUNKNOWN; 
     1271                } 
     1272            } 
     1273 
     1274            for (i = 0; i < ff->vfi->plane_cnt; ++i) { 
     1275                data[i] = q; 
     1276                q += vafp->plane_bytes[i]; 
     1277            } 
     1278            h = sws_scale(ff->sws_ctx, avframe.data, avframe.linesize, 0,  
     1279                          ff->dec_ctx->coded_height, data, vafp->strides); 
     1280            pj_assert((int)vafp->size.h == h); 
     1281#endif 
     1282 
     1283            pjmedia_format_id new_fmt_id; 
     1284            pj_status_t status; 
     1285 
     1286            /* Get current raw format id from ffmpeg decoder context */ 
     1287            status = PixelFormat_to_pjmedia_format_id(ff->dec_ctx->pix_fmt,  
     1288                                                      &new_fmt_id); 
     1289            if (status != PJ_SUCCESS) 
     1290                return status; 
     1291 
     1292            /* Update decoder format in param */ 
     1293            ff->param.dec_fmt.id = new_fmt_id; 
     1294            ff->param.dec_fmt.det.vid.size.w = ff->dec_ctx->coded_width; 
     1295            ff->param.dec_fmt.det.vid.size.h = ff->dec_ctx->coded_height; 
     1296 
     1297            /* Re-init format info and apply-param of decoder */ 
     1298            ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id); 
     1299            if (!ff->dec_vfi) 
     1300                return PJ_EUNKNOWN; 
     1301            pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp)); 
     1302            ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size; 
     1303            ff->dec_vafp.buffer = NULL; 
     1304            status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp); 
     1305            if (status != PJ_SUCCESS) 
     1306                return status; 
     1307 
     1308            /* Notify application via the bit_info field of pjmedia_frame */ 
     1309            output->bit_info = PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED; 
     1310        } 
     1311 
     1312        /* Check provided buffer size after format changed */ 
     1313        if (vafp->framebytes > output_buf_len) 
     1314            return PJ_ETOOSMALL; 
     1315 
     1316        /* Get the decoded data */ 
     1317        for (i = 0; i < ff->dec_vfi->plane_cnt; ++i) { 
     1318            pj_uint8_t *p = avframe.data[i]; 
     1319 
     1320            /* The decoded data may contain padding */ 
     1321            if (avframe.linesize[i]!=vafp->strides[i]) { 
     1322                /* Padding exists, copy line by line */ 
     1323                pj_uint8_t *q_end; 
     1324                     
     1325                q_end = q+vafp->plane_bytes[i]; 
     1326                while(q < q_end) { 
     1327                    pj_memcpy(q, p, vafp->strides[i]); 
     1328                    q += vafp->strides[i]; 
     1329                    p += avframe.linesize[i]; 
     1330                } 
     1331            } else { 
     1332                /* No padding, copy the whole plane */ 
     1333                pj_memcpy(q, p, vafp->plane_bytes[i]); 
     1334                q += vafp->plane_bytes[i]; 
     1335            } 
     1336        } 
     1337 
    10251338        output->size = vafp->framebytes; 
    10261339    } else { 
     
    10361349static pj_status_t  ffmpeg_codec_recover( pjmedia_vid_codec *codec,  
    10371350                                          unsigned output_buf_len,  
    1038                                           struct pjmedia_frame *output) 
    1039 { 
    1040     ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
    1041  
     1351                                          pjmedia_frame *output) 
     1352{ 
     1353    PJ_UNUSED_ARG(codec); 
    10421354    PJ_UNUSED_ARG(output_buf_len); 
    10431355    PJ_UNUSED_ARG(output); 
    1044     PJ_UNUSED_ARG(ff); 
    1045  
    1046     return PJ_SUCCESS; 
     1356 
     1357    return PJ_ENOTSUP; 
    10471358} 
    10481359 
    10491360#ifdef _MSC_VER 
    10501361#   pragma comment( lib, "avcodec.lib") 
     1362#   pragma comment( lib, "swscale.lib") 
    10511363#endif 
    10521364 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/colorbar_dev.c

    r3401 r3420  
    8181struct cbar_stream 
    8282{ 
    83     pjmedia_vid_stream   base;              /**< Base stream           */ 
    84     pjmedia_vid_param    param;             /**< Settings              */ 
    85     pj_pool_t           *pool;              /**< Memory pool.          */ 
    86  
    87     pjmedia_vid_cb       vid_cb;            /**< Stream callback.      */ 
    88     void                *user_data;         /**< Application data.     */ 
     83    pjmedia_vid_dev_stream           base;          /**< Base stream        */ 
     84    pjmedia_vid_param                param;         /**< Settings           */ 
     85    pj_pool_t                       *pool;          /**< Memory pool.       */ 
     86 
     87    pjmedia_vid_cb                   vid_cb;        /**< Stream callback.   */ 
     88    void                            *user_data;     /**< Application data.  */ 
    8989 
    9090    const struct cbar_fmt_info      *cbfi; 
     
    106106                                              unsigned index, 
    107107                                              pjmedia_vid_param *param); 
    108 static pj_status_t cbar_factory_create_stream(pjmedia_vid_dev_factory *f, 
    109                                               const pjmedia_vid_param *param, 
    110                                               const pjmedia_vid_cb *cb, 
    111                                               void *user_data, 
    112                                               pjmedia_vid_stream **p_vid_strm); 
    113  
    114 static pj_status_t cbar_stream_get_param(pjmedia_vid_stream *strm, 
     108static pj_status_t cbar_factory_create_stream( 
     109                                        pjmedia_vid_dev_factory *f, 
     110                                        const pjmedia_vid_param *param, 
     111                                        const pjmedia_vid_cb *cb, 
     112                                        void *user_data, 
     113                                        pjmedia_vid_dev_stream **p_vid_strm); 
     114 
     115static pj_status_t cbar_stream_get_param(pjmedia_vid_dev_stream *strm, 
    115116                                         pjmedia_vid_param *param); 
    116 static pj_status_t cbar_stream_get_cap(pjmedia_vid_stream *strm, 
     117static pj_status_t cbar_stream_get_cap(pjmedia_vid_dev_stream *strm, 
    117118                                       pjmedia_vid_dev_cap cap, 
    118119                                       void *value); 
    119 static pj_status_t cbar_stream_set_cap(pjmedia_vid_stream *strm, 
     120static pj_status_t cbar_stream_set_cap(pjmedia_vid_dev_stream *strm, 
    120121                                       pjmedia_vid_dev_cap cap, 
    121122                                       const void *value); 
    122 static pj_status_t cbar_stream_get_frame(pjmedia_vid_stream *strm, 
     123static pj_status_t cbar_stream_get_frame(pjmedia_vid_dev_stream *strm, 
    123124                                         pjmedia_frame *frame); 
    124 static pj_status_t cbar_stream_start(pjmedia_vid_stream *strm); 
    125 static pj_status_t cbar_stream_stop(pjmedia_vid_stream *strm); 
    126 static pj_status_t cbar_stream_destroy(pjmedia_vid_stream *strm); 
     125static pj_status_t cbar_stream_start(pjmedia_vid_dev_stream *strm); 
     126static pj_status_t cbar_stream_stop(pjmedia_vid_dev_stream *strm); 
     127static pj_status_t cbar_stream_destroy(pjmedia_vid_dev_stream *strm); 
    127128 
    128129/* Operations */ 
     
    137138}; 
    138139 
    139 static pjmedia_vid_stream_op stream_op = 
     140static pjmedia_vid_dev_stream_op stream_op = 
    140141{ 
    141142    &cbar_stream_get_param, 
     
    355356 
    356357/* API: create stream */ 
    357 static pj_status_t cbar_factory_create_stream(pjmedia_vid_dev_factory *f, 
    358                                               const pjmedia_vid_param *param, 
    359                                               const pjmedia_vid_cb *cb, 
    360                                               void *user_data, 
    361                                               pjmedia_vid_stream **p_vid_strm) 
     358static pj_status_t cbar_factory_create_stream( 
     359                                        pjmedia_vid_dev_factory *f, 
     360                                        const pjmedia_vid_param *param, 
     361                                        const pjmedia_vid_cb *cb, 
     362                                        void *user_data, 
     363                                        pjmedia_vid_dev_stream **p_vid_strm) 
    362364{ 
    363365    struct cbar_factory *cf = (struct cbar_factory*)f; 
     
    420422 
    421423/* API: Get stream info. */ 
    422 static pj_status_t cbar_stream_get_param(pjmedia_vid_stream *s, 
     424static pj_status_t cbar_stream_get_param(pjmedia_vid_dev_stream *s, 
    423425                                         pjmedia_vid_param *pi) 
    424426{ 
     
    439441 
    440442/* API: get capability */ 
    441 static pj_status_t cbar_stream_get_cap(pjmedia_vid_stream *s, 
     443static pj_status_t cbar_stream_get_cap(pjmedia_vid_dev_stream *s, 
    442444                                       pjmedia_vid_dev_cap cap, 
    443445                                       void *pval) 
     
    459461 
    460462/* API: set capability */ 
    461 static pj_status_t cbar_stream_set_cap(pjmedia_vid_stream *s, 
     463static pj_status_t cbar_stream_set_cap(pjmedia_vid_dev_stream *s, 
    462464                                       pjmedia_vid_dev_cap cap, 
    463465                                       const void *pval) 
     
    553555 
    554556/* API: Get frame from stream */ 
    555 static pj_status_t cbar_stream_get_frame(pjmedia_vid_stream *strm, 
     557static pj_status_t cbar_stream_get_frame(pjmedia_vid_dev_stream *strm, 
    556558                                         pjmedia_frame *frame) 
    557559{ 
     
    562564 
    563565/* API: Start stream. */ 
    564 static pj_status_t cbar_stream_start(pjmedia_vid_stream *strm) 
     566static pj_status_t cbar_stream_start(pjmedia_vid_dev_stream *strm) 
    565567{ 
    566568    struct cbar_stream *stream = (struct cbar_stream*)strm; 
     
    574576 
    575577/* API: Stop stream. */ 
    576 static pj_status_t cbar_stream_stop(pjmedia_vid_stream *strm) 
     578static pj_status_t cbar_stream_stop(pjmedia_vid_dev_stream *strm) 
    577579{ 
    578580    struct cbar_stream *stream = (struct cbar_stream*)strm; 
     
    587589 
    588590/* API: Destroy stream. */ 
    589 static pj_status_t cbar_stream_destroy(pjmedia_vid_stream *strm) 
     591static pj_status_t cbar_stream_destroy(pjmedia_vid_dev_stream *strm) 
    590592{ 
    591593    struct cbar_stream *stream = (struct cbar_stream*)strm; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshow_dev.c

    r3402 r3420  
    9090struct dshow_stream 
    9191{ 
    92     pjmedia_vid_stream   base;              /**< Base stream           */ 
    93     pjmedia_vid_param    param;             /**< Settings              */ 
    94     pj_pool_t           *pool;              /**< Memory pool.          */ 
    95  
    96     pjmedia_vid_cb       vid_cb;            /**< Stream callback.     */ 
    97     void                *user_data;         /**< Application data.     */ 
    98  
    99     pj_bool_t            quit_flag; 
    100     pj_bool_t            rend_thread_exited; 
    101     pj_bool_t            cap_thread_exited; 
    102     pj_bool_t            cap_thread_initialized; 
    103     pj_thread_desc       cap_thread_desc; 
    104     pj_thread_t         *cap_thread; 
     92    pjmedia_vid_dev_stream   base;                  /**< Base stream        */ 
     93    pjmedia_vid_param        param;                 /**< Settings           */ 
     94    pj_pool_t               *pool;                  /**< Memory pool.       */ 
     95 
     96    pjmedia_vid_cb           vid_cb;                /**< Stream callback.   */ 
     97    void                    *user_data;             /**< Application data.  */ 
     98 
     99    pj_bool_t                quit_flag; 
     100    pj_bool_t                rend_thread_exited; 
     101    pj_bool_t                cap_thread_exited; 
     102    pj_bool_t                cap_thread_initialized; 
     103    pj_thread_desc           cap_thread_desc; 
     104    pj_thread_t             *cap_thread; 
    105105 
    106106    struct dshow_graph 
     
    127127                                               unsigned index, 
    128128                                               pjmedia_vid_param *param); 
    129 static pj_status_t dshow_factory_create_stream(pjmedia_vid_dev_factory *f, 
    130                                                const pjmedia_vid_param *param, 
    131                                                const pjmedia_vid_cb *cb, 
    132                                                void *user_data, 
    133                                                pjmedia_vid_stream **p_vid_strm); 
    134  
    135 static pj_status_t dshow_stream_get_param(pjmedia_vid_stream *strm, 
     129static pj_status_t dshow_factory_create_stream( 
     130                                        pjmedia_vid_dev_factory *f, 
     131                                        const pjmedia_vid_param *param, 
     132                                        const pjmedia_vid_cb *cb, 
     133                                        void *user_data, 
     134                                        pjmedia_vid_dev_stream **p_vid_strm); 
     135 
     136static pj_status_t dshow_stream_get_param(pjmedia_vid_dev_stream *strm, 
    136137                                          pjmedia_vid_param *param); 
    137 static pj_status_t dshow_stream_get_cap(pjmedia_vid_stream *strm, 
     138static pj_status_t dshow_stream_get_cap(pjmedia_vid_dev_stream *strm, 
    138139                                        pjmedia_vid_dev_cap cap, 
    139140                                        void *value); 
    140 static pj_status_t dshow_stream_set_cap(pjmedia_vid_stream *strm, 
     141static pj_status_t dshow_stream_set_cap(pjmedia_vid_dev_stream *strm, 
    141142                                        pjmedia_vid_dev_cap cap, 
    142143                                        const void *value); 
    143 static pj_status_t dshow_stream_start(pjmedia_vid_stream *strm); 
    144 static pj_status_t dshow_stream_put_frame(pjmedia_vid_stream *strm, 
     144static pj_status_t dshow_stream_start(pjmedia_vid_dev_stream *strm); 
     145static pj_status_t dshow_stream_put_frame(pjmedia_vid_dev_stream *strm, 
    145146                                          const pjmedia_frame *frame); 
    146 static pj_status_t dshow_stream_stop(pjmedia_vid_stream *strm); 
    147 static pj_status_t dshow_stream_destroy(pjmedia_vid_stream *strm); 
     147static pj_status_t dshow_stream_stop(pjmedia_vid_dev_stream *strm); 
     148static pj_status_t dshow_stream_destroy(pjmedia_vid_dev_stream *strm); 
    148149 
    149150/* Operations */ 
     
    158159}; 
    159160 
    160 static pjmedia_vid_stream_op stream_op = 
     161static pjmedia_vid_dev_stream_op stream_op = 
    161162{ 
    162163    &dshow_stream_get_param, 
     
    396397    /* Set the device capabilities here */ 
    397398    param->clock_rate = DEFAULT_CLOCK_RATE; 
    398     param->frame_rate.num = DEFAULT_FPS; 
    399     param->frame_rate.denum = 1; 
     399    //param->frame_rate.num = DEFAULT_FPS; 
     400    //param->frame_rate.denum = 1; 
    400401    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT; 
    401402 
     
    439440 
    440441/* API: Put frame from stream */ 
    441 static pj_status_t dshow_stream_put_frame(pjmedia_vid_stream *strm, 
     442static pj_status_t dshow_stream_put_frame(pjmedia_vid_dev_stream *strm, 
    442443                                          const pjmedia_frame *frame) 
    443444{ 
     
    698699 
    699700/* API: create stream */ 
    700 static pj_status_t dshow_factory_create_stream(pjmedia_vid_dev_factory *f, 
    701                                                const pjmedia_vid_param *param, 
    702                                                const pjmedia_vid_cb *cb, 
    703                                                void *user_data, 
    704                                                pjmedia_vid_stream **p_vid_strm) 
     701static pj_status_t dshow_factory_create_stream( 
     702                                        pjmedia_vid_dev_factory *f, 
     703                                        const pjmedia_vid_param *param, 
     704                                        const pjmedia_vid_cb *cb, 
     705                                        void *user_data, 
     706                                        pjmedia_vid_dev_stream **p_vid_strm) 
    705707{ 
    706708    struct dshow_factory *df = (struct dshow_factory*)f; 
     
    753755  
    754756on_error: 
    755     dshow_stream_destroy((pjmedia_vid_stream *)strm); 
     757    dshow_stream_destroy((pjmedia_vid_dev_stream *)strm); 
    756758    return PJ_EUNKNOWN; 
    757759} 
    758760 
    759761/* API: Get stream info. */ 
    760 static pj_status_t dshow_stream_get_param(pjmedia_vid_stream *s, 
     762static pj_status_t dshow_stream_get_param(pjmedia_vid_dev_stream *s, 
    761763                                          pjmedia_vid_param *pi) 
    762764{ 
     
    777779 
    778780/* API: get capability */ 
    779 static pj_status_t dshow_stream_get_cap(pjmedia_vid_stream *s, 
     781static pj_status_t dshow_stream_get_cap(pjmedia_vid_dev_stream *s, 
    780782                                        pjmedia_vid_dev_cap cap, 
    781783                                        void *pval) 
     
    797799 
    798800/* API: set capability */ 
    799 static pj_status_t dshow_stream_set_cap(pjmedia_vid_stream *s, 
     801static pj_status_t dshow_stream_set_cap(pjmedia_vid_dev_stream *s, 
    800802                                        pjmedia_vid_dev_cap cap, 
    801803                                        const void *pval) 
     
    817819 
    818820/* API: Start stream. */ 
    819 static pj_status_t dshow_stream_start(pjmedia_vid_stream *strm) 
     821static pj_status_t dshow_stream_start(pjmedia_vid_dev_stream *strm) 
    820822{ 
    821823    struct dshow_stream *stream = (struct dshow_stream*)strm; 
     
    843845 
    844846/* API: Stop stream. */ 
    845 static pj_status_t dshow_stream_stop(pjmedia_vid_stream *strm) 
     847static pj_status_t dshow_stream_stop(pjmedia_vid_dev_stream *strm) 
    846848{ 
    847849    struct dshow_stream *stream = (struct dshow_stream*)strm; 
     
    869871 
    870872/* API: Destroy stream. */ 
    871 static pj_status_t dshow_stream_destroy(pjmedia_vid_stream *strm) 
     873static pj_status_t dshow_stream_destroy(pjmedia_vid_dev_stream *strm) 
    872874{ 
    873875    struct dshow_stream *stream = (struct dshow_stream*)strm; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c

    r3392 r3420  
    6868typedef struct ffmpeg_stream 
    6969{ 
    70     pjmedia_vid_stream           base; 
     70    pjmedia_vid_dev_stream       base; 
    7171    ffmpeg_factory              *factory; 
    7272    pj_pool_t                   *pool; 
     
    8181static unsigned    ffmpeg_factory_get_dev_count(pjmedia_vid_dev_factory *f); 
    8282static pj_status_t ffmpeg_factory_get_dev_info(pjmedia_vid_dev_factory *f, 
    83                                               unsigned index, 
    84                                               pjmedia_vid_dev_info *info); 
     83                                               unsigned index, 
     84                                               pjmedia_vid_dev_info *info); 
    8585static pj_status_t ffmpeg_factory_default_param(pj_pool_t *pool, 
    8686                                                pjmedia_vid_dev_factory *f, 
    8787                                                unsigned index, 
    8888                                                pjmedia_vid_param *param); 
    89 static pj_status_t ffmpeg_factory_create_stream(pjmedia_vid_dev_factory *f, 
    90                                                const pjmedia_vid_param *param, 
    91                                                const pjmedia_vid_cb *cb, 
    92                                                void *user_data, 
    93                                                pjmedia_vid_stream **p_vid_strm); 
    94  
    95 static pj_status_t ffmpeg_stream_get_param(pjmedia_vid_stream *strm, 
    96                                           pjmedia_vid_param *param); 
    97 static pj_status_t ffmpeg_stream_get_cap(pjmedia_vid_stream *strm, 
    98                                         pjmedia_vid_dev_cap cap, 
    99                                         void *value); 
    100 static pj_status_t ffmpeg_stream_set_cap(pjmedia_vid_stream *strm, 
    101                                         pjmedia_vid_dev_cap cap, 
    102                                         const void *value); 
    103 static pj_status_t ffmpeg_stream_start(pjmedia_vid_stream *strm); 
    104 static pj_status_t ffmpeg_stream_get_frame(pjmedia_vid_stream *s, 
     89static pj_status_t ffmpeg_factory_create_stream( 
     90                                        pjmedia_vid_dev_factory *f, 
     91                                        const pjmedia_vid_param *param, 
     92                                        const pjmedia_vid_cb *cb, 
     93                                        void *user_data, 
     94                                        pjmedia_vid_dev_stream **p_vid_strm); 
     95 
     96static pj_status_t ffmpeg_stream_get_param(pjmedia_vid_dev_stream *strm, 
     97                                           pjmedia_vid_param *param); 
     98static pj_status_t ffmpeg_stream_get_cap(pjmedia_vid_dev_stream *strm, 
     99                                         pjmedia_vid_dev_cap cap, 
     100                                         void *value); 
     101static pj_status_t ffmpeg_stream_set_cap(pjmedia_vid_dev_stream *strm, 
     102                                         pjmedia_vid_dev_cap cap, 
     103                                         const void *value); 
     104static pj_status_t ffmpeg_stream_start(pjmedia_vid_dev_stream *strm); 
     105static pj_status_t ffmpeg_stream_get_frame(pjmedia_vid_dev_stream *s, 
    105106                                           pjmedia_frame *frame); 
    106 static pj_status_t ffmpeg_stream_stop(pjmedia_vid_stream *strm); 
    107 static pj_status_t ffmpeg_stream_destroy(pjmedia_vid_stream *strm); 
     107static pj_status_t ffmpeg_stream_stop(pjmedia_vid_dev_stream *strm); 
     108static pj_status_t ffmpeg_stream_destroy(pjmedia_vid_dev_stream *strm); 
    108109 
    109110/* Operations */ 
     
    118119}; 
    119120 
    120 static pjmedia_vid_stream_op stream_op = 
     121static pjmedia_vid_dev_stream_op stream_op = 
    121122{ 
    122123    &ffmpeg_stream_get_param, 
     
    153154{ 
    154155    AVFormatParameters fp; 
    155     pjmedia_video_format_detail *fmt_detail; 
     156    pjmedia_video_format_detail *vfd; 
    156157    int err; 
    157158 
     
    160161                     PJ_EINVAL); 
    161162 
    162     fmt_detail = (pjmedia_video_format_detail*)param->fmt.detail; 
     163    vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE); 
    163164 
    164165    /* Init ffmpeg format context */ 
     
    168169    pj_bzero(&fp, sizeof(fp)); 
    169170    fp.prealloced_context = 1; 
    170     fp.width = fmt_detail->size.w; 
    171     fp.height = fmt_detail->size.h; 
     171    fp.width = vfd->size.w; 
     172    fp.height = vfd->size.h; 
    172173    fp.pix_fmt = PIX_FMT_BGR24; 
    173     fp.time_base.num = param->frame_rate.denum; 
    174     fp.time_base.den = param->frame_rate.num; 
     174    fp.time_base.num = vfd->fps.denum; 
     175    fp.time_base.den = vfd->fps.num; 
    175176 
    176177    /* Open capture stream */ 
     
    289290/* API: get device info */ 
    290291static pj_status_t ffmpeg_factory_get_dev_info(pjmedia_vid_dev_factory *f, 
    291                                               unsigned index, 
    292                                               pjmedia_vid_dev_info *info) 
     292                                               unsigned index, 
     293                                               pjmedia_vid_dev_info *info) 
    293294{ 
    294295    ffmpeg_factory *ff = (ffmpeg_factory*)f; 
     
    309310    ffmpeg_factory *ff = (ffmpeg_factory*)f; 
    310311    ffmpeg_dev_info *info; 
    311     pjmedia_video_format_detail *fmt_detail; 
    312312 
    313313    PJ_ASSERT_RETURN(index < ff->dev_count, PJMEDIA_EVID_INVDEV); 
     314 
     315    PJ_UNUSED_ARG(pool); 
     316 
    314317    info = &ff->dev_info[index]; 
    315318 
     
    322325    /* Set the device capabilities here */ 
    323326    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT; 
    324     pj_memcpy(&param->fmt, &info->base.fmt[0], sizeof(param->fmt)); 
    325327    param->clock_rate = 90000; 
    326     pjmedia_format_init_video(pool, &param->fmt, 320, 240, 25, 1, 
    327                               0, 0); 
    328     fmt_detail = (pjmedia_video_format_detail*)param->fmt.detail; 
    329     param->frame_rate.num = fmt_detail->fps.num; 
    330     param->frame_rate.denum = fmt_detail->fps.denum; 
     328    pjmedia_format_init_video(&param->fmt, 0, 320, 240, 25, 1); 
     329    param->fmt.id = info->base.fmt[0].id; 
    331330 
    332331    return PJ_SUCCESS; 
     
    336335 
    337336/* API: create stream */ 
    338 static pj_status_t ffmpeg_factory_create_stream(pjmedia_vid_dev_factory *f, 
    339                                                const pjmedia_vid_param *param, 
    340                                                const pjmedia_vid_cb *cb, 
    341                                                void *user_data, 
    342                                                pjmedia_vid_stream **p_vid_strm) 
     337static pj_status_t ffmpeg_factory_create_stream( 
     338                                        pjmedia_vid_dev_factory *f, 
     339                                        const pjmedia_vid_param *param, 
     340                                        const pjmedia_vid_cb *cb, 
     341                                        void *user_data, 
     342                                        pjmedia_vid_dev_stream **p_vid_strm) 
    343343{ 
    344344    ffmpeg_factory *ff = (ffmpeg_factory*)f; 
     
    349349    PJ_ASSERT_RETURN(param->dir == PJMEDIA_DIR_CAPTURE, PJ_EINVAL); 
    350350    PJ_ASSERT_RETURN((unsigned)param->cap_id < ff->dev_count, PJ_EINVAL); 
    351     PJ_ASSERT_RETURN(param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO && 
    352                      param->fmt.detail, PJ_EINVAL); 
     351    PJ_ASSERT_RETURN(param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO, 
     352                    PJ_EINVAL); 
    353353 
    354354    PJ_UNUSED_ARG(cb); 
     
    372372 
    373373/* API: Get stream info. */ 
    374 static pj_status_t ffmpeg_stream_get_param(pjmedia_vid_stream *s, 
     374static pj_status_t ffmpeg_stream_get_param(pjmedia_vid_dev_stream *s, 
    375375                                           pjmedia_vid_param *pi) 
    376376{ 
     
    385385 
    386386/* API: get capability */ 
    387 static pj_status_t ffmpeg_stream_get_cap(pjmedia_vid_stream *s, 
    388                                         pjmedia_vid_dev_cap cap, 
    389                                         void *pval) 
     387static pj_status_t ffmpeg_stream_get_cap(pjmedia_vid_dev_stream *s, 
     388                                         pjmedia_vid_dev_cap cap, 
     389                                         void *pval) 
    390390{ 
    391391    ffmpeg_stream *strm = (ffmpeg_stream*)s; 
     
    399399 
    400400/* API: set capability */ 
    401 static pj_status_t ffmpeg_stream_set_cap(pjmedia_vid_stream *s, 
    402                                         pjmedia_vid_dev_cap cap, 
    403                                         const void *pval) 
     401static pj_status_t ffmpeg_stream_set_cap(pjmedia_vid_dev_stream *s, 
     402                                         pjmedia_vid_dev_cap cap, 
     403                                         const void *pval) 
    404404{ 
    405405    ffmpeg_stream *strm = (ffmpeg_stream*)s; 
     
    414414 
    415415/* API: Start stream. */ 
    416 static pj_status_t ffmpeg_stream_start(pjmedia_vid_stream *s) 
     416static pj_status_t ffmpeg_stream_start(pjmedia_vid_dev_stream *s) 
    417417{ 
    418418    ffmpeg_stream *strm = (ffmpeg_stream*)s; 
     
    436436 
    437437/* API: Get frame from stream */ 
    438 static pj_status_t ffmpeg_stream_get_frame(pjmedia_vid_stream *s, 
     438static pj_status_t ffmpeg_stream_get_frame(pjmedia_vid_dev_stream *s, 
    439439                                           pjmedia_frame *frame) 
    440440{ 
     
    459459 
    460460/* API: Stop stream. */ 
    461 static pj_status_t ffmpeg_stream_stop(pjmedia_vid_stream *s) 
     461static pj_status_t ffmpeg_stream_stop(pjmedia_vid_dev_stream *s) 
    462462{ 
    463463    ffmpeg_stream *strm = (ffmpeg_stream*)s; 
     
    473473 
    474474/* API: Destroy stream. */ 
    475 static pj_status_t ffmpeg_stream_destroy(pjmedia_vid_stream *s) 
     475static pj_status_t ffmpeg_stream_destroy(pjmedia_vid_dev_stream *s) 
    476476{ 
    477477    ffmpeg_stream *strm = (ffmpeg_stream*)s; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c

    r3401 r3420  
    9191struct sdl_stream 
    9292{ 
    93     pjmedia_vid_stream   base;              /**< Base stream           */ 
    94     pjmedia_vid_param    param;             /**< Settings              */ 
    95     pj_pool_t           *pool;              /**< Memory pool.          */ 
    96  
    97     pjmedia_vid_cb       vid_cb;            /**< Stream callback.      */ 
    98     void                *user_data;         /**< Application data.     */ 
    99  
    100     pj_thread_t         *sdl_thread;        /**< SDL thread.           */ 
    101     pj_bool_t            is_quitting; 
    102     pj_bool_t            is_running; 
    103     pj_bool_t            render_exited; 
    104     pj_status_t          status; 
    105  
    106     SDL_Rect             rect;              /**< Display rectangle.    */ 
    107     SDL_Surface         *screen;            /**< Display screen.       */ 
    108     SDL_Surface         *surf;              /**< RGB surface.          */ 
    109     SDL_Overlay         *overlay;           /**< YUV overlay.          */ 
     93    pjmedia_vid_dev_stream       base;              /**< Base stream        */ 
     94    pjmedia_vid_param            param;             /**< Settings           */ 
     95    pj_pool_t                   *pool;              /**< Memory pool.       */ 
     96 
     97    pjmedia_vid_cb               vid_cb;            /**< Stream callback.   */ 
     98    void                        *user_data;         /**< Application data.  */ 
     99 
     100    pj_thread_t                 *sdl_thread;        /**< SDL thread.        */ 
     101    pj_bool_t                    is_quitting; 
     102    pj_bool_t                    is_running; 
     103    pj_bool_t                    render_exited; 
     104    pj_status_t                  status; 
     105 
     106    SDL_Rect                     rect;              /**< Display rectangle. */ 
     107    SDL_Surface                 *screen;            /**< Display screen.    */ 
     108    SDL_Surface                 *surf;              /**< RGB surface.       */ 
     109    SDL_Overlay                 *overlay;           /**< YUV overlay.       */ 
    110110 
    111111    /* For frame conversion */ 
    112     pjmedia_converter       *conv; 
    113     pjmedia_conversion_param conv_param; 
    114     pjmedia_frame            conv_buf; 
     112    pjmedia_converter           *conv; 
     113    pjmedia_conversion_param    conv_param; 
     114    pjmedia_frame                conv_buf; 
    115115 
    116116    pjmedia_video_apply_fmt_param vafp; 
     
    129129                                             unsigned index, 
    130130                                             pjmedia_vid_param *param); 
    131 static pj_status_t sdl_factory_create_stream(pjmedia_vid_dev_factory *f, 
    132                                              const pjmedia_vid_param *param, 
    133                                              const pjmedia_vid_cb *cb, 
    134                                              void *user_data, 
    135                                              pjmedia_vid_stream **p_vid_strm); 
    136  
    137 static pj_status_t sdl_stream_get_param(pjmedia_vid_stream *strm, 
     131static pj_status_t sdl_factory_create_stream( 
     132                                        pjmedia_vid_dev_factory *f, 
     133                                        const pjmedia_vid_param *param, 
     134                                        const pjmedia_vid_cb *cb, 
     135                                        void *user_data, 
     136                                        pjmedia_vid_dev_stream **p_vid_strm); 
     137 
     138static pj_status_t sdl_stream_get_param(pjmedia_vid_dev_stream *strm, 
    138139                                        pjmedia_vid_param *param); 
    139 static pj_status_t sdl_stream_get_cap(pjmedia_vid_stream *strm, 
     140static pj_status_t sdl_stream_get_cap(pjmedia_vid_dev_stream *strm, 
    140141                                      pjmedia_vid_dev_cap cap, 
    141142                                      void *value); 
    142 static pj_status_t sdl_stream_set_cap(pjmedia_vid_stream *strm, 
     143static pj_status_t sdl_stream_set_cap(pjmedia_vid_dev_stream *strm, 
    143144                                      pjmedia_vid_dev_cap cap, 
    144145                                      const void *value); 
    145 static pj_status_t sdl_stream_put_frame(pjmedia_vid_stream *strm, 
     146static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm, 
    146147                                        const pjmedia_frame *frame); 
    147 static pj_status_t sdl_stream_start(pjmedia_vid_stream *strm); 
    148 static pj_status_t sdl_stream_stop(pjmedia_vid_stream *strm); 
    149 static pj_status_t sdl_stream_destroy(pjmedia_vid_stream *strm); 
     148static pj_status_t sdl_stream_start(pjmedia_vid_dev_stream *strm); 
     149static pj_status_t sdl_stream_stop(pjmedia_vid_dev_stream *strm); 
     150static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm); 
    150151 
    151152/* Operations */ 
     
    160161}; 
    161162 
    162 static pjmedia_vid_stream_op stream_op = 
     163static pjmedia_vid_dev_stream_op stream_op = 
    163164{ 
    164165    &sdl_stream_get_param, 
     
    408409                        } 
    409410                    if (strm->is_running) 
    410                         pjmedia_vid_stream_stop(&strm->base); 
     411                        pjmedia_vid_dev_stream_stop(&strm->base); 
    411412                    else 
    412                         pjmedia_vid_stream_start(&strm->base); 
     413                        pjmedia_vid_dev_stream_start(&strm->base); 
    413414                    break; 
    414415                case SDL_VIDEORESIZE: 
     
    434435                     * To process PJMEDIA_EVENT_WINDOW_CLOSE event, 
    435436                     * application should do this in the on_event_cb callback: 
    436                      * 1. stop further calls to #pjmedia_vid_stream_put_frame() 
     437                     * 1. stop further calls to  
     438                     *    #pjmedia_vid_dev_stream_put_frame() 
    437439                     * 2. return PJ_SUCCESS 
    438440                     * Upon returning from the callback, SDL will destroy its 
     
    484486 
    485487/* API: create stream */ 
    486 static pj_status_t sdl_factory_create_stream(pjmedia_vid_dev_factory *f, 
    487                                              const pjmedia_vid_param *param, 
    488                                              const pjmedia_vid_cb *cb, 
    489                                              void *user_data, 
    490                                              pjmedia_vid_stream **p_vid_strm) 
     488static pj_status_t sdl_factory_create_stream( 
     489                                        pjmedia_vid_dev_factory *f, 
     490                                        const pjmedia_vid_param *param, 
     491                                        const pjmedia_vid_cb *cb, 
     492                                        void *user_data, 
     493                                        pjmedia_vid_dev_stream **p_vid_strm) 
    491494{ 
    492495    struct sdl_factory *sf = (struct sdl_factory*)f; 
     
    549552 
    550553/* API: Get stream info. */ 
    551 static pj_status_t sdl_stream_get_param(pjmedia_vid_stream *s, 
     554static pj_status_t sdl_stream_get_param(pjmedia_vid_dev_stream *s, 
    552555                                        pjmedia_vid_param *pi) 
    553556{ 
     
    568571 
    569572/* API: get capability */ 
    570 static pj_status_t sdl_stream_get_cap(pjmedia_vid_stream *s, 
     573static pj_status_t sdl_stream_get_cap(pjmedia_vid_dev_stream *s, 
    571574                                      pjmedia_vid_dev_cap cap, 
    572575                                      void *pval) 
     
    587590 
    588591/* API: set capability */ 
    589 static pj_status_t sdl_stream_set_cap(pjmedia_vid_stream *s, 
     592static pj_status_t sdl_stream_set_cap(pjmedia_vid_dev_stream *s, 
    590593                                      pjmedia_vid_dev_cap cap, 
    591594                                      const void *pval) 
     
    606609 
    607610/* API: Put frame from stream */ 
    608 static pj_status_t sdl_stream_put_frame(pjmedia_vid_stream *strm, 
     611static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm, 
    609612                                        const pjmedia_frame *frame) 
    610613{ 
     
    665668 
    666669/* API: Start stream. */ 
    667 static pj_status_t sdl_stream_start(pjmedia_vid_stream *strm) 
     670static pj_status_t sdl_stream_start(pjmedia_vid_dev_stream *strm) 
    668671{ 
    669672    struct sdl_stream *stream = (struct sdl_stream*)strm; 
     
    678681 
    679682/* API: Stop stream. */ 
    680 static pj_status_t sdl_stream_stop(pjmedia_vid_stream *strm) 
     683static pj_status_t sdl_stream_stop(pjmedia_vid_dev_stream *strm) 
    681684{ 
    682685    struct sdl_stream *stream = (struct sdl_stream*)strm; 
     
    695698 
    696699/* API: Destroy stream. */ 
    697 static pj_status_t sdl_stream_destroy(pjmedia_vid_stream *strm) 
     700static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm) 
    698701{ 
    699702    struct sdl_stream *stream = (struct sdl_stream*)strm; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/videodev.c

    r3395 r3420  
    425425    unsigned i; 
    426426 
    427     /* Allow shutdown() to be called multiple times as long as there is matching 
    428      * number of init(). 
     427    /* Allow shutdown() to be called multiple times as long as there is 
     428     * matching number of init(). 
    429429     */ 
    430430    if (vid_subsys.init_count == 0) { 
     
    547547 
    548548    for (drv_idx=0; drv_idx<vid_subsys.drv_cnt; ++drv_idx) { 
    549         if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name)) { 
     549        if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name)) 
     550        { 
    550551            f = vid_subsys.drv[drv_idx].f; 
    551552            break; 
     
    556557        return PJ_ENOTFOUND; 
    557558 
    558     for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx) { 
     559    for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx) 
     560    { 
    559561        pjmedia_vid_dev_info info; 
    560562        pj_status_t status; 
     
    607609 
    608610/* API: Open video stream object using the specified parameters. */ 
    609 PJ_DEF(pj_status_t) pjmedia_vid_stream_create(const pjmedia_vid_param *prm, 
    610                                               const pjmedia_vid_cb *cb, 
    611                                               void *user_data, 
    612                                               pjmedia_vid_stream **p_vid_strm) 
     611PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_create( 
     612                                        const pjmedia_vid_param *prm, 
     613                                        const pjmedia_vid_cb *cb, 
     614                                        void *user_data, 
     615                                        pjmedia_vid_dev_stream **p_vid_strm) 
    613616{ 
    614617    pjmedia_vid_dev_factory *cap_f=NULL, *rend_f=NULL, *f=NULL; 
     
    675678 
    676679/* API: Get the running parameters for the specified video stream. */ 
    677 PJ_DEF(pj_status_t) pjmedia_vid_stream_get_param(pjmedia_vid_stream *strm, 
    678                                                  pjmedia_vid_param *param) 
     680PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_param( 
     681                                            pjmedia_vid_dev_stream *strm, 
     682                                            pjmedia_vid_param *param) 
    679683{ 
    680684    pj_status_t status; 
     
    695699 
    696700/* API: Get the value of a specific capability of the video stream. */ 
    697 PJ_DEF(pj_status_t) pjmedia_vid_stream_get_cap(pjmedia_vid_stream *strm, 
    698                                                pjmedia_vid_dev_cap cap, 
    699                                                void *value) 
     701PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_cap( 
     702                                            pjmedia_vid_dev_stream *strm, 
     703                                            pjmedia_vid_dev_cap cap, 
     704                                            void *value) 
    700705{ 
    701706    return strm->op->get_cap(strm, cap, value); 
     
    703708 
    704709/* API: Set the value of a specific capability of the video stream. */ 
    705 PJ_DEF(pj_status_t) pjmedia_vid_stream_set_cap(pjmedia_vid_stream *strm, 
    706                                                pjmedia_vid_dev_cap cap, 
    707                                                const void *value) 
     710PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_set_cap( 
     711                                            pjmedia_vid_dev_stream *strm, 
     712                                            pjmedia_vid_dev_cap cap, 
     713                                            const void *value) 
    708714{ 
    709715    return strm->op->set_cap(strm, cap, value); 
     
    711717 
    712718/* API: Start the stream. */ 
    713 PJ_DEF(pj_status_t) pjmedia_vid_stream_start(pjmedia_vid_stream *strm) 
     719PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm) 
    714720{ 
    715721    return strm->op->start(strm); 
    716722} 
    717723 
    718 PJ_DEF(pj_status_t) pjmedia_vid_stream_get_frame(pjmedia_vid_stream *strm, 
    719                                                  pjmedia_frame *frame) 
     724PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_frame( 
     725                                            pjmedia_vid_dev_stream *strm, 
     726                                            pjmedia_frame *frame) 
    720727{ 
    721728    pj_assert(strm->op->get_frame); 
     
    723730} 
    724731 
    725 PJ_DEF(pj_status_t) pjmedia_vid_stream_put_frame(pjmedia_vid_stream *strm, 
    726                                                  const pjmedia_frame *frame) 
     732PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_put_frame( 
     733                                            pjmedia_vid_dev_stream *strm, 
     734                                            const pjmedia_frame *frame) 
    727735{ 
    728736    pj_assert(strm->op->put_frame); 
     
    731739 
    732740/* API: Stop the stream. */ 
    733 PJ_DEF(pj_status_t) pjmedia_vid_stream_stop(pjmedia_vid_stream *strm) 
     741PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_stop(pjmedia_vid_dev_stream *strm) 
    734742{ 
    735743    return strm->op->stop(strm); 
     
    737745 
    738746/* API: Destroy the stream. */ 
    739 PJ_DEF(pj_status_t) pjmedia_vid_stream_destroy(pjmedia_vid_stream *strm) 
     747PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_destroy( 
     748                                                pjmedia_vid_dev_stream *strm) 
    740749{ 
    741750    return strm->op->destroy(strm); 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/jbuf.c

    r3359 r3420  
    6969    pj_size_t       *content_len;       /**< frame length array             */ 
    7070    pj_uint32_t     *bit_info;          /**< frame bit info array           */ 
     71    pj_uint32_t     *ts;                /**< timestamp array                */ 
    7172     
    7273    /* States */ 
     
    198199                                            sizeof(framelist->bit_info[0])* 
    199200                                            framelist->max_count); 
    200  
     201    framelist->ts           = (pj_uint32_t*) 
     202                              pj_pool_alloc(pool,  
     203                                            sizeof(framelist->ts[0])* 
     204                                            framelist->max_count); 
    201205 
    202206    return jb_framelist_reset(framelist); 
     
    259263                                  void *frame, pj_size_t *size, 
    260264                                  pjmedia_jb_frame_type *p_type, 
    261                                   pj_uint32_t *bit_info)  
     265                                  pj_uint32_t *bit_info, 
     266                                  pj_uint32_t *ts)  
    262267{ 
    263268    if (framelist->size) { 
     
    282287            if (bit_info) 
    283288                *bit_info = framelist->bit_info[framelist->head]; 
     289            if (ts) 
     290                *ts = framelist->ts[framelist->head]; 
    284291 
    285292            //pj_bzero(framelist->content +  
     
    289296            framelist->content_len[framelist->head] = 0; 
    290297            framelist->bit_info[framelist->head] = 0; 
     298            framelist->ts[framelist->head] = 0; 
    291299 
    292300            framelist->origin++; 
     
    302310 
    303311    return PJ_FALSE; 
     312} 
     313 
     314 
     315static pj_bool_t jb_framelist_peek(jb_framelist_t *framelist, 
     316                                   unsigned idx, 
     317                                   const void **frame, 
     318                                   pj_size_t *size, 
     319                                   pjmedia_jb_frame_type *type, 
     320                                   pj_uint32_t *bit_info, 
     321                                   pj_uint32_t *ts)  
     322{ 
     323    unsigned pos; 
     324 
     325    if (idx >= jb_framelist_eff_size(framelist)) 
     326        return PJ_FALSE; 
     327 
     328    pos = framelist->head; 
     329 
     330    /* Find actual peek position, note there may be discarded frames */ 
     331    while (1) { 
     332        if (framelist->frame_type[pos] != PJMEDIA_JB_DISCARDED_FRAME) { 
     333            if (idx == 0) 
     334                break; 
     335            else 
     336                --idx; 
     337        } 
     338        pos = (pos + 1) % framelist->max_count; 
     339    } 
     340 
     341    /* Return the frame pointer */ 
     342    if (frame) 
     343        *frame = framelist->content + pos*framelist->frame_size; 
     344    if (type) 
     345        *type = (pjmedia_jb_frame_type)  
     346                framelist->frame_type[pos]; 
     347    if (size) 
     348        *size = framelist->content_len[pos]; 
     349    if (bit_info) 
     350        *bit_info = framelist->bit_info[pos]; 
     351    if (ts) 
     352        *ts = framelist->ts[pos]; 
     353 
     354    return PJ_TRUE; 
    304355} 
    305356 
     
    373424                                       unsigned frame_size, 
    374425                                       pj_uint32_t bit_info, 
     426                                       pj_uint32_t ts, 
    375427                                       unsigned frame_type) 
    376428{ 
     
    426478    framelist->content_len[pos] = frame_size; 
    427479    framelist->bit_info[pos] = bit_info; 
     480    framelist->ts[pos] = ts; 
    428481 
    429482    /* update framelist size */ 
     
    735788                                     int frame_seq) 
    736789{ 
    737     pjmedia_jbuf_put_frame2(jb, frame, frame_size, 0, frame_seq, NULL); 
     790    pjmedia_jbuf_put_frame3(jb, frame, frame_size, 0, frame_seq, 0, NULL); 
    738791} 
    739792 
     
    743796                                     pj_uint32_t bit_info, 
    744797                                     int frame_seq, 
     798                                     pj_bool_t *discarded) 
     799{ 
     800    pjmedia_jbuf_put_frame3(jb, frame, frame_size, bit_info, frame_seq, 0,  
     801                            discarded); 
     802} 
     803 
     804PJ_DEF(void) pjmedia_jbuf_put_frame3(pjmedia_jbuf *jb,  
     805                                     const void *frame,  
     806                                     pj_size_t frame_size,  
     807                                     pj_uint32_t bit_info, 
     808                                     int frame_seq, 
     809                                     pj_uint32_t ts, 
    745810                                     pj_bool_t *discarded) 
    746811{ 
     
    812877    min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size); 
    813878    status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 
    814                                  min_frame_size, bit_info, frame_type); 
     879                                 min_frame_size, bit_info, ts, frame_type); 
    815880     
    816881    /* Jitter buffer is full, remove some older frames */ 
     
    835900        removed = jb_framelist_remove_head(&jb->jb_framelist, distance); 
    836901        status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 
    837                                      min_frame_size, bit_info, frame_type); 
     902                                     min_frame_size, bit_info, ts, frame_type); 
    838903 
    839904        jb->jb_discard += removed; 
     
    867932                                     char *p_frame_type) 
    868933{ 
    869     pjmedia_jbuf_get_frame2(jb, frame, NULL, p_frame_type, NULL); 
     934    pjmedia_jbuf_get_frame3(jb, frame, NULL, p_frame_type, NULL, NULL); 
    870935} 
    871936 
     
    879944                                     pj_uint32_t *bit_info) 
    880945{ 
     946    pjmedia_jbuf_get_frame3(jb, frame, size, p_frame_type, bit_info, NULL); 
     947} 
     948 
     949/* 
     950 * Get frame from jitter buffer. 
     951 */ 
     952PJ_DEF(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,  
     953                                     void *frame,  
     954                                     pj_size_t *size, 
     955                                     char *p_frame_type, 
     956                                     pj_uint32_t *bit_info, 
     957                                     pj_uint32_t *ts) 
     958{ 
    881959    if (jb->jb_status == JB_STATUS_PREFETCHING) { 
    882960 
     
    902980        /* Try to retrieve a frame from frame list */ 
    903981        res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype,  
    904                                bit_info); 
     982                               bit_info, ts); 
    905983        if (res) { 
    906984            /* We've successfully retrieved a frame from the frame list, but 
     
    9701048} 
    9711049 
     1050 
     1051PJ_DEF(void) pjmedia_jbuf_peek_frame( pjmedia_jbuf *jb, 
     1052                                      unsigned idx, 
     1053                                      const void **frame,  
     1054                                      pj_size_t *size,  
     1055                                      char *p_frm_type, 
     1056                                      pj_uint32_t *bit_info, 
     1057                                      pj_uint32_t *ts) 
     1058{ 
     1059    pjmedia_jb_frame_type ftype; 
     1060    pj_bool_t res; 
     1061 
     1062    res = jb_framelist_peek(&jb->jb_framelist, idx, frame, size, &ftype, bit_info, ts); 
     1063    if (!res) 
     1064        *p_frm_type = PJMEDIA_JB_ZERO_EMPTY_FRAME; 
     1065    else if (ftype == PJMEDIA_JB_NORMAL_FRAME) 
     1066        *p_frm_type = PJMEDIA_JB_NORMAL_FRAME; 
     1067    else 
     1068        *p_frm_type = PJMEDIA_JB_MISSING_FRAME; 
     1069} 
     1070 
     1071 
     1072PJ_DEF(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb,  
     1073                                           unsigned frame_cnt) 
     1074{ 
     1075    unsigned count, last_discard_num; 
     1076 
     1077    last_discard_num = jb->jb_framelist.discarded_num; 
     1078    count = jb_framelist_remove_head(&jb->jb_framelist, frame_cnt); 
     1079 
     1080    /* Remove some more when there were discarded frames included */ 
     1081    while (jb->jb_framelist.discarded_num < last_discard_num) { 
     1082        /* Calculate frames count to be removed next */ 
     1083        frame_cnt = last_discard_num - jb->jb_framelist.discarded_num; 
     1084 
     1085        /* Normalize non-discarded frames count just been removed */ 
     1086        count -= frame_cnt; 
     1087 
     1088        /* Remove more frames */ 
     1089        last_discard_num = jb->jb_framelist.discarded_num; 
     1090        count += jb_framelist_remove_head(&jb->jb_framelist, frame_cnt); 
     1091    } 
     1092 
     1093    return count; 
     1094} 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/stream.c

    r3418 r3420  
    2323#include <pjmedia/rtcp.h> 
    2424#include <pjmedia/jbuf.h> 
     25#include <pjmedia/stream_common.h> 
    2526#include <pj/array.h> 
    2627#include <pj/assert.h> 
     
    27392740} 
    27402741 
     2742 
     2743static const pj_str_t ID_AUDIO = { "audio", 5}; 
     2744static const pj_str_t ID_VIDEO = { "video", 5}; 
     2745static const pj_str_t ID_APPLICATION = { "application", 11}; 
     2746static const pj_str_t ID_IN = { "IN", 2 }; 
     2747static const pj_str_t ID_IP4 = { "IP4", 3}; 
     2748static const pj_str_t ID_IP6 = { "IP6", 3}; 
     2749static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 }; 
     2750static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 }; 
     2751//static const pj_str_t ID_SDP_NAME = { "pjmedia", 7 }; 
     2752static const pj_str_t ID_RTPMAP = { "rtpmap", 6 }; 
     2753static const pj_str_t ID_TELEPHONE_EVENT = { "telephone-event", 15 }; 
     2754 
     2755static const pj_str_t STR_INACTIVE = { "inactive", 8 }; 
     2756static const pj_str_t STR_SENDRECV = { "sendrecv", 8 }; 
     2757static const pj_str_t STR_SENDONLY = { "sendonly", 8 }; 
     2758static const pj_str_t STR_RECVONLY = { "recvonly", 8 }; 
     2759 
     2760 
     2761/* 
     2762 * Internal function for collecting codec info and param from the SDP media. 
     2763 */ 
     2764static pj_status_t get_audio_codec_info_param(pjmedia_stream_info *si, 
     2765                                              pj_pool_t *pool, 
     2766                                              pjmedia_codec_mgr *mgr, 
     2767                                              const pjmedia_sdp_media *local_m, 
     2768                                              const pjmedia_sdp_media *rem_m) 
     2769{ 
     2770    const pjmedia_sdp_attr *attr; 
     2771    pjmedia_sdp_rtpmap *rtpmap; 
     2772    unsigned i, fmti, pt = 0; 
     2773    pj_status_t status; 
     2774 
     2775    /* Find the first codec which is not telephone-event */ 
     2776    for ( fmti = 0; fmti < local_m->desc.fmt_count; ++fmti ) { 
     2777        if ( !pj_isdigit(*local_m->desc.fmt[fmti].ptr) ) 
     2778            return PJMEDIA_EINVALIDPT; 
     2779        pt = pj_strtoul(&local_m->desc.fmt[fmti]); 
     2780        if ( PJMEDIA_RTP_PT_TELEPHONE_EVENTS == 0 || 
     2781                pt != PJMEDIA_RTP_PT_TELEPHONE_EVENTS ) 
     2782                break; 
     2783    } 
     2784    if ( fmti >= local_m->desc.fmt_count ) 
     2785        return PJMEDIA_EINVALIDPT; 
     2786 
     2787    /* Get codec info. 
     2788     * For static payload types, get the info from codec manager. 
     2789     * For dynamic payload types, MUST get the rtpmap. 
     2790     */ 
     2791    if (pt < 96) { 
     2792        pj_bool_t has_rtpmap; 
     2793 
     2794        rtpmap = NULL; 
     2795        has_rtpmap = PJ_TRUE; 
     2796 
     2797        attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,  
     2798                                           &local_m->desc.fmt[fmti]); 
     2799        if (attr == NULL) { 
     2800            has_rtpmap = PJ_FALSE; 
     2801        } 
     2802        if (attr != NULL) { 
     2803            status = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap); 
     2804            if (status != PJ_SUCCESS) 
     2805                has_rtpmap = PJ_FALSE; 
     2806        } 
     2807 
     2808        /* Build codec format info: */ 
     2809        if (has_rtpmap) { 
     2810            si->fmt.type = si->type; 
     2811            si->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]); 
     2812            pj_strdup(pool, &si->fmt.encoding_name, &rtpmap->enc_name); 
     2813            si->fmt.clock_rate = rtpmap->clock_rate; 
     2814             
     2815#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG != 0) 
     2816            /* The session info should have the actual clock rate, because  
     2817             * this info is used for calculationg buffer size, etc in stream  
     2818             */ 
     2819            if (si->fmt.pt == PJMEDIA_RTP_PT_G722) 
     2820                si->fmt.clock_rate = 16000; 
     2821#endif 
     2822 
     2823            /* For audio codecs, rtpmap parameters denotes the number of 
     2824             * channels. 
     2825             */ 
     2826            if (si->type == PJMEDIA_TYPE_AUDIO && rtpmap->param.slen) { 
     2827                si->fmt.channel_cnt = (unsigned) pj_strtoul(&rtpmap->param); 
     2828            } else { 
     2829                si->fmt.channel_cnt = 1; 
     2830            } 
     2831 
     2832        } else {             
     2833            const pjmedia_codec_info *p_info; 
     2834 
     2835            status = pjmedia_codec_mgr_get_codec_info( mgr, pt, &p_info); 
     2836            if (status != PJ_SUCCESS) 
     2837                return status; 
     2838 
     2839            pj_memcpy(&si->fmt, p_info, sizeof(pjmedia_codec_info)); 
     2840        } 
     2841 
     2842        /* For static payload type, pt's are symetric */ 
     2843        si->tx_pt = pt; 
     2844 
     2845    } else { 
     2846 
     2847        attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,  
     2848                                           &local_m->desc.fmt[fmti]); 
     2849        if (attr == NULL) 
     2850            return PJMEDIA_EMISSINGRTPMAP; 
     2851 
     2852        status = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap); 
     2853        if (status != PJ_SUCCESS) 
     2854            return status; 
     2855 
     2856        /* Build codec format info: */ 
     2857 
     2858        si->fmt.type = si->type; 
     2859        si->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]); 
     2860        pj_strdup(pool, &si->fmt.encoding_name, &rtpmap->enc_name); 
     2861        si->fmt.clock_rate = rtpmap->clock_rate; 
     2862 
     2863        /* For audio codecs, rtpmap parameters denotes the number of 
     2864         * channels. 
     2865         */ 
     2866        if (si->type == PJMEDIA_TYPE_AUDIO && rtpmap->param.slen) { 
     2867            si->fmt.channel_cnt = (unsigned) pj_strtoul(&rtpmap->param); 
     2868        } else { 
     2869            si->fmt.channel_cnt = 1; 
     2870        } 
     2871 
     2872        /* Determine payload type for outgoing channel, by finding 
     2873         * dynamic payload type in remote SDP that matches the answer. 
     2874         */ 
     2875        si->tx_pt = 0xFFFF; 
     2876        for (i=0; i<rem_m->desc.fmt_count; ++i) { 
     2877            unsigned rpt; 
     2878            pjmedia_sdp_attr *r_attr; 
     2879            pjmedia_sdp_rtpmap r_rtpmap; 
     2880 
     2881            rpt = pj_strtoul(&rem_m->desc.fmt[i]); 
     2882            if (rpt < 96) 
     2883                continue; 
     2884 
     2885            r_attr = pjmedia_sdp_media_find_attr(rem_m, &ID_RTPMAP, 
     2886                                                 &rem_m->desc.fmt[i]); 
     2887            if (!r_attr) 
     2888                continue; 
     2889 
     2890            if (pjmedia_sdp_attr_get_rtpmap(r_attr, &r_rtpmap) != PJ_SUCCESS) 
     2891                continue; 
     2892 
     2893            if (!pj_stricmp(&rtpmap->enc_name, &r_rtpmap.enc_name) && 
     2894                rtpmap->clock_rate == r_rtpmap.clock_rate) 
     2895            { 
     2896                /* Found matched codec. */ 
     2897                si->tx_pt = rpt; 
     2898 
     2899                break; 
     2900            } 
     2901        } 
     2902 
     2903        if (si->tx_pt == 0xFFFF) 
     2904            return PJMEDIA_EMISSINGRTPMAP; 
     2905    } 
     2906 
     2907   
     2908    /* Now that we have codec info, get the codec param. */ 
     2909    si->param = PJ_POOL_ALLOC_T(pool, pjmedia_codec_param); 
     2910    status = pjmedia_codec_mgr_get_default_param(mgr, &si->fmt, 
     2911                                                 si->param); 
     2912 
     2913    /* Get remote fmtp for our encoder. */ 
     2914    pjmedia_stream_info_parse_fmtp(pool, rem_m, si->tx_pt, 
     2915                                   &si->param->setting.enc_fmtp); 
     2916 
     2917    /* Get local fmtp for our decoder. */ 
     2918    pjmedia_stream_info_parse_fmtp(pool, local_m, si->fmt.pt,  
     2919                                   &si->param->setting.dec_fmtp); 
     2920 
     2921    /* Get the remote ptime for our encoder. */ 
     2922    attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 
     2923                                  "ptime", NULL); 
     2924    if (attr) { 
     2925        pj_str_t tmp_val = attr->value; 
     2926        unsigned frm_per_pkt; 
     2927  
     2928        pj_strltrim(&tmp_val); 
     2929 
     2930        /* Round up ptime when the specified is not multiple of frm_ptime */ 
     2931        frm_per_pkt = (pj_strtoul(&tmp_val) +  
     2932                      si->param->info.frm_ptime/2) / 
     2933                      si->param->info.frm_ptime; 
     2934        if (frm_per_pkt != 0) { 
     2935            si->param->setting.frm_per_pkt = (pj_uint8_t)frm_per_pkt; 
     2936        } 
     2937    } 
     2938 
     2939    /* Get remote maxptime for our encoder. */ 
     2940    attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 
     2941                                  "maxptime", NULL); 
     2942    if (attr) { 
     2943        pj_str_t tmp_val = attr->value; 
     2944 
     2945        pj_strltrim(&tmp_val); 
     2946        si->tx_maxptime = pj_strtoul(&tmp_val); 
     2947    } 
     2948 
     2949    /* When direction is NONE (it means SDP negotiation has failed) we don't 
     2950     * need to return a failure here, as returning failure will cause 
     2951     * the whole SDP to be rejected. See ticket #: 
     2952     *  http:// 
     2953     * 
     2954     * Thanks Alain Totouom  
     2955     */ 
     2956    if (status != PJ_SUCCESS && si->dir != PJMEDIA_DIR_NONE) 
     2957        return status; 
     2958 
     2959 
     2960    /* Get incomming payload type for telephone-events */ 
     2961    si->rx_event_pt = -1; 
     2962    for (i=0; i<local_m->attr_count; ++i) { 
     2963        pjmedia_sdp_rtpmap r; 
     2964 
     2965        attr = local_m->attr[i]; 
     2966        if (pj_strcmp(&attr->name, &ID_RTPMAP) != 0) 
     2967            continue; 
     2968        if (pjmedia_sdp_attr_get_rtpmap(attr, &r) != PJ_SUCCESS) 
     2969            continue; 
     2970        if (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) == 0) { 
     2971            si->rx_event_pt = pj_strtoul(&r.pt); 
     2972            break; 
     2973        } 
     2974    } 
     2975 
     2976    /* Get outgoing payload type for telephone-events */ 
     2977    si->tx_event_pt = -1; 
     2978    for (i=0; i<rem_m->attr_count; ++i) { 
     2979        pjmedia_sdp_rtpmap r; 
     2980 
     2981        attr = rem_m->attr[i]; 
     2982        if (pj_strcmp(&attr->name, &ID_RTPMAP) != 0) 
     2983            continue; 
     2984        if (pjmedia_sdp_attr_get_rtpmap(attr, &r) != PJ_SUCCESS) 
     2985            continue; 
     2986        if (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) == 0) { 
     2987            si->tx_event_pt = pj_strtoul(&r.pt); 
     2988            break; 
     2989        } 
     2990    } 
     2991 
     2992    return PJ_SUCCESS; 
     2993} 
     2994 
     2995 
     2996 
     2997/* 
     2998 * Create stream info from SDP media line. 
     2999 */ 
     3000PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp( 
     3001                                           pjmedia_stream_info *si, 
     3002                                           pj_pool_t *pool, 
     3003                                           pjmedia_endpt *endpt, 
     3004                                           const pjmedia_sdp_session *local, 
     3005                                           const pjmedia_sdp_session *remote, 
     3006                                           unsigned stream_idx) 
     3007{ 
     3008    pjmedia_codec_mgr *mgr; 
     3009    const pjmedia_sdp_attr *attr; 
     3010    const pjmedia_sdp_media *local_m; 
     3011    const pjmedia_sdp_media *rem_m; 
     3012    const pjmedia_sdp_conn *local_conn; 
     3013    const pjmedia_sdp_conn *rem_conn; 
     3014    int rem_af, local_af; 
     3015    pj_sockaddr local_addr; 
     3016    pj_status_t status; 
     3017 
     3018     
     3019    /* Validate arguments: */ 
     3020    PJ_ASSERT_RETURN(pool && si && local && remote, PJ_EINVAL); 
     3021    PJ_ASSERT_RETURN(stream_idx < local->media_count, PJ_EINVAL); 
     3022    PJ_ASSERT_RETURN(stream_idx < remote->media_count, PJ_EINVAL); 
     3023 
     3024    /* Keep SDP shortcuts */ 
     3025    local_m = local->media[stream_idx]; 
     3026    rem_m = remote->media[stream_idx]; 
     3027 
     3028    local_conn = local_m->conn ? local_m->conn : local->conn; 
     3029    if (local_conn == NULL) 
     3030        return PJMEDIA_SDP_EMISSINGCONN; 
     3031 
     3032    rem_conn = rem_m->conn ? rem_m->conn : remote->conn; 
     3033    if (rem_conn == NULL) 
     3034        return PJMEDIA_SDP_EMISSINGCONN; 
     3035 
     3036    /* Media type must be audio */ 
     3037    if (pj_stricmp(&local_m->desc.media, &ID_AUDIO) == 0) 
     3038        return PJMEDIA_EINVALIMEDIATYPE; 
     3039 
     3040    /* Get codec manager. */ 
     3041    mgr = pjmedia_endpt_get_codec_mgr(endpt); 
     3042 
     3043    /* Reset: */ 
     3044 
     3045    pj_bzero(si, sizeof(*si)); 
     3046 
     3047#if PJMEDIA_HAS_RTCP_XR && PJMEDIA_STREAM_ENABLE_XR 
     3048    /* Set default RTCP XR enabled/disabled */ 
     3049    si->rtcp_xr_enabled = PJ_TRUE; 
     3050#endif 
     3051 
     3052    /* Media type: */ 
     3053    si->type = PJMEDIA_TYPE_AUDIO; 
     3054 
     3055    /* Transport protocol */ 
     3056 
     3057    /* At this point, transport type must be compatible,  
     3058     * the transport instance will do more validation later. 
     3059     */ 
     3060    status = pjmedia_sdp_transport_cmp(&rem_m->desc.transport,  
     3061                                       &local_m->desc.transport); 
     3062    if (status != PJ_SUCCESS) 
     3063        return PJMEDIA_SDPNEG_EINVANSTP; 
     3064 
     3065    if (pj_stricmp(&local_m->desc.transport, &ID_RTP_AVP) == 0) { 
     3066 
     3067        si->proto = PJMEDIA_TP_PROTO_RTP_AVP; 
     3068 
     3069    } else if (pj_stricmp(&local_m->desc.transport, &ID_RTP_SAVP) == 0) { 
     3070 
     3071        si->proto = PJMEDIA_TP_PROTO_RTP_SAVP; 
     3072 
     3073    } else { 
     3074 
     3075        si->proto = PJMEDIA_TP_PROTO_UNKNOWN; 
     3076        return PJ_SUCCESS; 
     3077    } 
     3078 
     3079 
     3080    /* Check address family in remote SDP */ 
     3081    rem_af = pj_AF_UNSPEC(); 
     3082    if (pj_stricmp(&rem_conn->net_type, &ID_IN)==0) { 
     3083        if (pj_stricmp(&rem_conn->addr_type, &ID_IP4)==0) { 
     3084            rem_af = pj_AF_INET(); 
     3085        } else if (pj_stricmp(&rem_conn->addr_type, &ID_IP6)==0) { 
     3086            rem_af = pj_AF_INET6(); 
     3087        } 
     3088    } 
     3089 
     3090    if (rem_af==pj_AF_UNSPEC()) { 
     3091        /* Unsupported address family */ 
     3092        return PJ_EAFNOTSUP; 
     3093    } 
     3094 
     3095    /* Set remote address: */ 
     3096    status = pj_sockaddr_init(rem_af, &si->rem_addr, &rem_conn->addr,  
     3097                              rem_m->desc.port); 
     3098    if (status != PJ_SUCCESS) { 
     3099        /* Invalid IP address. */ 
     3100        return PJMEDIA_EINVALIDIP; 
     3101    } 
     3102 
     3103    /* Check address family of local info */ 
     3104    local_af = pj_AF_UNSPEC(); 
     3105    if (pj_stricmp(&local_conn->net_type, &ID_IN)==0) { 
     3106        if (pj_stricmp(&local_conn->addr_type, &ID_IP4)==0) { 
     3107            local_af = pj_AF_INET(); 
     3108        } else if (pj_stricmp(&local_conn->addr_type, &ID_IP6)==0) { 
     3109            local_af = pj_AF_INET6(); 
     3110        } 
     3111    } 
     3112 
     3113    if (local_af==pj_AF_UNSPEC()) { 
     3114        /* Unsupported address family */ 
     3115        return PJ_SUCCESS; 
     3116    } 
     3117 
     3118    /* Set remote address: */ 
     3119    status = pj_sockaddr_init(local_af, &local_addr, &local_conn->addr,  
     3120                              local_m->desc.port); 
     3121    if (status != PJ_SUCCESS) { 
     3122        /* Invalid IP address. */ 
     3123        return PJMEDIA_EINVALIDIP; 
     3124    } 
     3125 
     3126    /* Local and remote address family must match */ 
     3127    if (local_af != rem_af) 
     3128        return PJ_EAFNOTSUP; 
     3129 
     3130    /* Media direction: */ 
     3131 
     3132    if (local_m->desc.port == 0 ||  
     3133        pj_sockaddr_has_addr(&local_addr)==PJ_FALSE || 
     3134        pj_sockaddr_has_addr(&si->rem_addr)==PJ_FALSE || 
     3135        pjmedia_sdp_media_find_attr(local_m, &STR_INACTIVE, NULL)!=NULL) 
     3136    { 
     3137        /* Inactive stream. */ 
     3138 
     3139        si->dir = PJMEDIA_DIR_NONE; 
     3140 
     3141    } else if (pjmedia_sdp_media_find_attr(local_m, &STR_SENDONLY, NULL)!=NULL) { 
     3142 
     3143        /* Send only stream. */ 
     3144 
     3145        si->dir = PJMEDIA_DIR_ENCODING; 
     3146 
     3147    } else if (pjmedia_sdp_media_find_attr(local_m, &STR_RECVONLY, NULL)!=NULL) { 
     3148 
     3149        /* Recv only stream. */ 
     3150 
     3151        si->dir = PJMEDIA_DIR_DECODING; 
     3152 
     3153    } else { 
     3154 
     3155        /* Send and receive stream. */ 
     3156 
     3157        si->dir = PJMEDIA_DIR_ENCODING_DECODING; 
     3158 
     3159    } 
     3160 
     3161    /* No need to do anything else if stream is rejected */ 
     3162    if (local_m->desc.port == 0) { 
     3163        return PJ_SUCCESS; 
     3164    } 
     3165 
     3166    /* If "rtcp" attribute is present in the SDP, set the RTCP address 
     3167     * from that attribute. Otherwise, calculate from RTP address. 
     3168     */ 
     3169    attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 
     3170                                  "rtcp", NULL); 
     3171    if (attr) { 
     3172        pjmedia_sdp_rtcp_attr rtcp; 
     3173        status = pjmedia_sdp_attr_get_rtcp(attr, &rtcp); 
     3174        if (status == PJ_SUCCESS) { 
     3175            if (rtcp.addr.slen) { 
     3176                status = pj_sockaddr_init(rem_af, &si->rem_rtcp, &rtcp.addr, 
     3177                                          (pj_uint16_t)rtcp.port); 
     3178            } else { 
     3179                pj_sockaddr_init(rem_af, &si->rem_rtcp, NULL,  
     3180                                 (pj_uint16_t)rtcp.port); 
     3181                pj_memcpy(pj_sockaddr_get_addr(&si->rem_rtcp), 
     3182                          pj_sockaddr_get_addr(&si->rem_addr), 
     3183                          pj_sockaddr_get_addr_len(&si->rem_addr)); 
     3184            } 
     3185        } 
     3186    } 
     3187     
     3188    if (!pj_sockaddr_has_addr(&si->rem_rtcp)) { 
     3189        int rtcp_port; 
     3190 
     3191        pj_memcpy(&si->rem_rtcp, &si->rem_addr, sizeof(pj_sockaddr)); 
     3192        rtcp_port = pj_sockaddr_get_port(&si->rem_addr) + 1; 
     3193        pj_sockaddr_set_port(&si->rem_rtcp, (pj_uint16_t)rtcp_port); 
     3194    } 
     3195 
     3196 
     3197    /* Get the payload number for receive channel. */ 
     3198    /* 
     3199       Previously we used to rely on fmt[0] being the selected codec, 
     3200       but some UA sends telephone-event as fmt[0] and this would 
     3201       cause assert failure below. 
     3202 
     3203       Thanks Chris Hamilton <chamilton .at. cs.dal.ca> for this patch. 
     3204 
     3205    // And codec must be numeric! 
     3206    if (!pj_isdigit(*local_m->desc.fmt[0].ptr) ||  
     3207        !pj_isdigit(*rem_m->desc.fmt[0].ptr)) 
     3208    { 
     3209        return PJMEDIA_EINVALIDPT; 
     3210    } 
     3211 
     3212    pt = pj_strtoul(&local_m->desc.fmt[0]); 
     3213    pj_assert(PJMEDIA_RTP_PT_TELEPHONE_EVENTS==0 || 
     3214              pt != PJMEDIA_RTP_PT_TELEPHONE_EVENTS); 
     3215    */ 
     3216 
     3217    /* Get codec info and param */ 
     3218    status = get_audio_codec_info_param(si, pool, mgr, local_m, rem_m); 
     3219 
     3220    /* Leave SSRC to random. */ 
     3221    si->ssrc = pj_rand(); 
     3222 
     3223    /* Set default jitter buffer parameter. */ 
     3224    si->jb_init = si->jb_max = si->jb_min_pre = si->jb_max_pre = -1; 
     3225 
     3226    return status; 
     3227} 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_codec.c

    r3392 r3420  
    2929static pjmedia_vid_codec_mgr *def_vid_codec_mgr; 
    3030 
    31 /* Definition of default codecs parameters */ 
    32 struct pjmedia_vid_codec_default_param 
    33 { 
    34     pjmedia_vid_codec_param     *param; 
     31 
     32/* 
     33 * Codec manager maintains array of these structs for each supported 
     34 * codec. 
     35 */ 
     36typedef struct pjmedia_vid_codec_desc 
     37{ 
     38    pjmedia_vid_codec_info           info;      /**< Codec info.            */ 
     39    pjmedia_codec_id                 id;        /**< Fully qualified name   */ 
     40    pjmedia_codec_priority           prio;      /**< Priority.              */ 
     41    pjmedia_vid_codec_factory       *factory;   /**< The factory.           */ 
     42    pjmedia_vid_codec_param         *def_param; /**< Default codecs  
     43                                                     parameters.            */ 
     44} pjmedia_vid_codec_desc; 
     45 
     46 
     47/* The declaration of video codec manager */ 
     48struct pjmedia_vid_codec_mgr 
     49{ 
     50    /** Codec manager mutex. */ 
     51    pj_mutex_t                  *mutex; 
     52 
     53    /** List of codec factories registered to codec manager. */ 
     54    pjmedia_vid_codec_factory    factory_list; 
     55 
     56    /** Number of supported codecs. */ 
     57    unsigned                     codec_cnt; 
     58 
     59    /** Array of codec descriptor. */ 
     60    pjmedia_vid_codec_desc       codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS]; 
     61 
    3562}; 
     63 
    3664 
    3765 
     
    94122PJ_DEF(pjmedia_vid_codec_mgr*) pjmedia_vid_codec_mgr_instance(void) 
    95123{ 
    96     pj_assert(def_vid_codec_mgr); 
     124    //pj_assert(def_vid_codec_mgr); 
    97125    return def_vid_codec_mgr; 
    98126} 
     
    616644                  &param->dec_fmtp.param[i].val); 
    617645    } 
    618     for (i = 0; i < param->dec_fmtp.cnt; ++i) { 
    619         pj_strdup(pool, &p->dec_fmtp.param[i].name,  
    620                   &param->dec_fmtp.param[i].name); 
    621         pj_strdup(pool, &p->dec_fmtp.param[i].val,  
    622                   &param->dec_fmtp.param[i].val); 
     646    for (i = 0; i < param->enc_fmtp.cnt; ++i) { 
     647        pj_strdup(pool, &p->enc_fmtp.param[i].name,  
     648                  &param->enc_fmtp.param[i].name); 
     649        pj_strdup(pool, &p->enc_fmtp.param[i].val,  
     650                  &param->enc_fmtp.param[i].val); 
    623651    } 
    624652 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/videoport.c

    r3402 r3420  
    3838    pjmedia_dir          dir; 
    3939    pjmedia_rect_size    cap_size; 
    40     pjmedia_vid_stream  *strm; 
     40    pjmedia_vid_dev_stream      *strm; 
    4141    pjmedia_vid_cb       strm_cb; 
    4242    void                *strm_cb_data; 
     
    7575}; 
    7676 
    77 static pj_status_t vidstream_cap_cb(pjmedia_vid_stream *stream, 
     77static pj_status_t vidstream_cap_cb(pjmedia_vid_dev_stream *stream, 
    7878                                    void *user_data, 
    7979                                    pjmedia_frame *frame); 
    80 static pj_status_t vidstream_render_cb(pjmedia_vid_stream *stream, 
     80static pj_status_t vidstream_render_cb(pjmedia_vid_dev_stream *stream, 
    8181                                       void *user_data, 
    8282                                       pjmedia_frame *frame); 
    83 static pj_status_t vidstream_event_cb(pjmedia_vid_stream *stream, 
     83static pj_status_t vidstream_event_cb(pjmedia_vid_dev_stream *stream, 
    8484                                      void *user_data, 
    8585                                      pjmedia_vid_event *event); 
     
    171171    vid_cb.on_event_cb = &vidstream_event_cb; 
    172172 
    173     status = pjmedia_vid_stream_create(&prm->vidparam, &vid_cb, vp, 
    174                                        &vp->strm); 
     173    status = pjmedia_vid_dev_stream_create(&prm->vidparam, &vid_cb, vp, 
     174                                           &vp->strm); 
    175175    if (status != PJ_SUCCESS) 
    176176        goto on_error; 
     
    278278} 
    279279 
    280 PJ_DEF(pjmedia_vid_stream*) 
     280PJ_DEF(pjmedia_vid_dev_stream*) 
    281281pjmedia_vid_port_get_stream(pjmedia_vid_port *vp) 
    282282{ 
     
    357357    PJ_ASSERT_RETURN(vp, PJ_EINVAL); 
    358358 
    359     status = pjmedia_vid_stream_start(vp->strm); 
     359    status = pjmedia_vid_dev_stream_start(vp->strm); 
    360360    if (status != PJ_SUCCESS) 
    361361        goto on_error; 
     
    386386    PJ_ASSERT_RETURN(vp, PJ_EINVAL); 
    387387 
    388     status = pjmedia_vid_stream_stop(vp->strm); 
     388    status = pjmedia_vid_dev_stream_stop(vp->strm); 
    389389 
    390390    if (vp->enc_clock) { 
     
    414414    } 
    415415    if (vp->strm) { 
    416         pjmedia_vid_stream_destroy(vp->strm); 
     416        pjmedia_vid_dev_stream_destroy(vp->strm); 
    417417        vp->strm = NULL; 
    418418    } 
     
    478478        return; 
    479479 
    480     status = pjmedia_vid_stream_get_frame(vp->strm, vp->enc_frm_buf); 
     480    status = pjmedia_vid_dev_stream_get_frame(vp->strm, vp->enc_frm_buf); 
    481481    if (status != PJ_SUCCESS) 
    482482        return; 
     
    581581                } else 
    582582                    vp->rend_sync_clocksrc.nsync_progress += ndrop; 
     583 
    583584                for (i = 0; i < ndrop; i++) { 
    584585                    status = pjmedia_port_get_frame(vp->client_port, 
     
    603604    pjmedia_clock_src_update(&vp->rend_clocksrc, NULL); 
    604605 
    605     status = pjmedia_vid_stream_put_frame(vp->strm, vp->dec_frm_buf); 
     606    status = pjmedia_vid_dev_stream_put_frame(vp->strm, vp->dec_frm_buf); 
    606607} 
    607608 
     
    615616} 
    616617 
    617 static pj_status_t vidstream_cap_cb(pjmedia_vid_stream *stream, 
     618static pj_status_t vidstream_cap_cb(pjmedia_vid_dev_stream *stream, 
    618619                                    void *user_data, 
    619620                                    pjmedia_frame *frame) 
     
    634635} 
    635636 
    636 static pj_status_t vidstream_render_cb(pjmedia_vid_stream *stream, 
     637static pj_status_t vidstream_render_cb(pjmedia_vid_dev_stream *stream, 
    637638                                       void *user_data, 
    638639                                       pjmedia_frame *frame) 
     
    653654} 
    654655 
    655 static pj_status_t vidstream_event_cb(pjmedia_vid_stream *stream, 
     656static pj_status_t vidstream_event_cb(pjmedia_vid_dev_stream *stream, 
    656657                                      void *user_data, 
    657658                                      pjmedia_vid_event *event) 
     
    671672 
    672673    if (vp->stream_role==ROLE_PASSIVE) { 
    673         return pjmedia_vid_stream_put_frame(vp->strm, frame); 
     674        return pjmedia_vid_dev_stream_put_frame(vp->strm, frame); 
    674675    } else { 
    675676        pj_mutex_lock(vp->dec_frm_mutex); 
     
    688689 
    689690    if (vp->stream_role==ROLE_PASSIVE) { 
    690         return pjmedia_vid_stream_get_frame(vp->strm, frame); 
     691        return pjmedia_vid_dev_stream_get_frame(vp->strm, frame); 
    691692    } else { 
    692693        pj_mutex_lock(vp->enc_frm_mutex); 
Note: See TracChangeset for help on using the changeset viewer.