Changeset 3493


Ignore:
Timestamp:
Mar 31, 2011 5:29:54 PM (9 years ago)
Author:
nanang
Message:

Re #1219:

  • Initial version of H264 implementation (codec & packetization).
  • Added vid_codec_util.h/c for video codec utilities (e.g: fmtp parser).
  • Updated video RTP packetizations to be configurable and have internal state (to be more resilient to packet lost, etc).
  • Fixed wrong SPF calculation in PJMEDIA_SPF2.
  • Updated vid_codec_test.c to also have RTP packetization test.
  • Updated sdp_neg.c to verify H.264 capability match.
Location:
pjproject/branches/projects/2.0-dev/pjmedia
Files:
5 added
10 edited

Legend:

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

    r3484 r3493  
    6767                        stream_common.o stream.o tonegen.o transport_adapter_sample.o \ 
    6868                        transport_ice.o transport_loop.o \ 
    69                         transport_srtp.o transport_udp.o vid_codec.o videoport.o vid_stream.o \ 
     69                        transport_srtp.o transport_udp.o vid_codec.o vid_codec_util.o \ 
     70                        videoport.o vid_stream.o \ 
    7071                        wav_player.o wav_playlist.o wav_writer.o wave.o \ 
    7172                        wsola.o 
     
    110111export PJMEDIA_CODEC_SRCDIR = ../src/pjmedia-codec 
    111112export PJMEDIA_CODEC_OBJS += ffmpeg_codecs.o \ 
     113                        h263_packetizer.o h264_packetizer.o \ 
    112114                        $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ 
    113115                        ipp_codecs.o $(CODEC_OBJS) 
  • pjproject/branches/projects/2.0-dev/pjmedia/build/pjmedia.vcproj

    r3420 r3493  
    46934693                        </File> 
    46944694                        <File 
     4695                                RelativePath="..\src\pjmedia\vid_codec_util.c" 
     4696                                > 
     4697                        </File> 
     4698                        <File 
    46954699                                RelativePath="..\src\pjmedia\vid_stream.c" 
    46964700                                > 
     
    51345138                        </File> 
    51355139                        <File 
     5140                                RelativePath="..\include\pjmedia\vid_codec_util.h" 
     5141                                > 
     5142                        </File> 
     5143                        <File 
    51365144                                RelativePath="..\include\pjmedia\vid_stream.h" 
    51375145                                > 
  • pjproject/branches/projects/2.0-dev/pjmedia/build/pjmedia_codec.vcproj

    r3394 r3493  
    28342834                                        /> 
    28352835                                </FileConfiguration> 
     2836                        </File> 
     2837                        <File 
     2838                                RelativePath="..\src\pjmedia-codec\h263_packetizer.c" 
     2839                                > 
     2840                        </File> 
     2841                        <File 
     2842                                RelativePath="..\src\pjmedia-codec\h264_packetizer.c" 
     2843                                > 
    28362844                        </File> 
    28372845                        <File 
     
    30713079                        </File> 
    30723080                        <File 
     3081                                RelativePath="..\include\pjmedia-codec\h264_packetizer.h" 
     3082                                > 
     3083                        </File> 
     3084                        <File 
    30733085                                RelativePath="..\include\pjmedia-codec\ilbc.h" 
    30743086                                > 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-codec/h263_packetizer.h

    r3486 r3493  
    2323/** 
    2424 * @file h263_packetizer.h 
    25  * @brief Packetizes H.263 bitstream into RTP payload. 
     25 * @brief Packetizes/unpacketizes H.263 bitstream into RTP payload. 
    2626 */ 
    2727 
    28 #include <pj/errno.h> 
     28#include <pj/pool.h> 
     29#include <pj/types.h> 
    2930 
    3031PJ_BEGIN_DECL 
    3132 
    32 /** 
    33  * Find synchronization point (PSC, slice, GSBC, EOS, EOSBS) in H.263  
    34  * bitstream, in reversed manner. 
    35  */ 
    36 PJ_INLINE(pj_uint8_t*) pjmedia_h263_find_sync_point_rev(pj_uint8_t *data, 
    37                                                         pj_size_t data_len) 
    38 { 
    39     pj_uint8_t *p = data+data_len-1; 
    40  
    41     while (p > data && *p && *(p+1)) 
    42         --p; 
    43  
    44     if (p == data) 
    45         return (data + data_len); 
    46          
    47     return p; 
    48 } 
    4933 
    5034/** 
    51  * Generate an RTP payload from H.263 frame bitstream, in-place processing. 
     35 * Opaque declaration for H.263 packetizer. 
    5236 */ 
    53 PJ_INLINE(pj_status_t) pjmedia_h263_packetize(pj_uint8_t *buf, 
    54                                               pj_size_t buf_len, 
    55                                               unsigned *pos, 
    56                                               int max_payload_len, 
    57                                               const pj_uint8_t **payload, 
    58                                               pj_size_t *payload_len) 
    59 { 
    60     pj_uint8_t *p, *p_end; 
     37typedef struct pjmedia_h263_packetizer pjmedia_h263_packetizer; 
    6138 
    62     p = buf + *pos; 
    63     p_end = buf + buf_len; 
    64  
    65     /* Put two octets payload header */ 
    66     if ((p_end-p > 2) && *p==0 && *(p+1)==0) { 
    67         /* The bitstream starts with synchronization point, just override 
    68          * the two zero octets (sync point mark) for payload header. 
    69          */ 
    70         *p = 0x04; 
    71     } else { 
    72         /* Not started in synchronization point, we will use two octets 
    73          * preceeding the bitstream for payload header! 
    74          */ 
    75  
    76         if (*pos < 2) { 
    77             /* Invalid H263 bitstream, it's not started with PSC */ 
    78             return PJ_EINVAL; 
    79         } 
    80  
    81         p -= 2; 
    82         *p = 0; 
    83     } 
    84     *(p+1) = 0; 
    85  
    86     /* When bitstream truncation needed because of payload length/MTU  
    87      * limitation, try to use sync point for the payload boundary. 
    88      */ 
    89     if (p_end-p > max_payload_len) { 
    90         p_end = pjmedia_h263_find_sync_point_rev(p+2, max_payload_len-2); 
    91     } 
    92  
    93     *payload = p; 
    94     *payload_len = p_end-p; 
    95     *pos = p_end - buf; 
    96  
    97     return PJ_SUCCESS; 
    98 } 
    9939 
    10040/** 
    101  * Append RTP payload to a H.263 picture bitstream. 
     41 * Enumeration of H.263 packetization modes. 
    10242 */ 
    103 PJ_INLINE(pj_status_t) pjmedia_h263_unpacketize(const pj_uint8_t *payload, 
    104                                                 pj_size_t   payload_len, 
    105                                                 pj_uint8_t *bits, 
    106                                                 pj_size_t  *bits_len) 
     43typedef enum 
    10744{ 
    108     pj_uint8_t P, V, PLEN; 
    109     const pj_uint8_t *p=payload; 
    110     pj_size_t max_len = *bits_len; 
     45    /** 
     46     * H.263 RTP packetization using RFC 4629. 
     47     */ 
     48    PJMEDIA_H263_PACKETIZER_MODE_RFC4629, 
    11149 
    112     P = *p & 0x04; 
    113     V = *p & 0x02; 
    114     PLEN = ((*p & 0x01) << 5) + ((*(p+1) & 0xF8)>>3); 
     50    /** 
     51     * H.263 RTP packetization using legacy RFC 2190. 
     52     * This is currently not supported. 
     53     */ 
     54    PJMEDIA_H263_PACKETIZER_MODE_RFC2190, 
    11555 
    116     /* Get bitstream pointer */ 
    117     p += 2; 
    118     if (V) 
    119         p += 1; /* Skip VRC data */ 
    120     if (PLEN) 
    121         p += PLEN; /* Skip extra picture header data */ 
     56} pjmedia_h263_packetizer_mode; 
    12257 
    123     /* Get bitstream length */ 
    124     payload_len -= (p-payload); 
    12558 
    126     *bits_len = payload_len + (P?2:0); 
    127     PJ_ASSERT_RETURN(max_len >= *bits_len, PJ_ETOOSMALL); 
     59/** 
     60 * H.263 packetizer configuration. 
     61 */ 
     62typedef struct pjmedia_h263_packetizer_cfg 
     63{ 
     64    /** 
     65     * Maximum payload length. 
     66     * Default: PJMEDIA_MAX_MTU 
     67     */ 
     68    int mtu; 
    12869 
    129     /* Add two zero octets when payload flagged with sync point */ 
    130     if (P) { 
    131         *bits++ = 0; 
    132         *bits++ = 0; 
    133     } 
     70    /** 
     71     * Packetization mode. 
     72     * Default: PJMEDIA_H263_PACKETIZER_MODE_RFC4629 
     73     */ 
     74    pjmedia_h263_packetizer_mode mode; 
    13475 
    135     /* Add the bitstream */ 
    136     pj_memcpy(bits, p, payload_len); 
     76} pjmedia_h263_packetizer_cfg; 
    13777 
    138     return PJ_SUCCESS; 
    139 } 
     78 
     79/** 
     80 * Create H.263 packetizer. 
     81 * 
     82 * @param pool          The memory pool. 
     83 * @param cfg           Packetizer settings, if NULL, default setting 
     84 *                      will be used. 
     85 * @param p_pktz        Pointer to receive the packetizer. 
     86 * 
     87 * @return              PJ_SUCCESS on success. 
     88 */ 
     89PJ_DECL(pj_status_t) pjmedia_h263_packetizer_create( 
     90                                    pj_pool_t *pool, 
     91                                    const pjmedia_h263_packetizer_cfg *cfg, 
     92                                    pjmedia_h263_packetizer **p_pktz); 
     93 
     94 
     95/** 
     96 * Generate an RTP payload from a H.263 picture bitstream. Note that this 
     97 * function will apply in-place processing, so the bitstream may be modified 
     98 * during the packetization. 
     99 * 
     100 * @param pktz          The packetizer. 
     101 * @param bits          The picture bitstream to be packetized. 
     102 * @param bits_len      The length of the bitstream. 
     103 * @param bits_pos      The bitstream offset to be packetized. 
     104 * @param payload       The output payload. 
     105 * @param payload_len   The output payload length. 
     106 * 
     107 * @return              PJ_SUCCESS on success. 
     108 */ 
     109PJ_DECL(pj_status_t) pjmedia_h263_packetize(pjmedia_h263_packetizer *pktz, 
     110                                            pj_uint8_t *bits, 
     111                                            pj_size_t bits_len, 
     112                                            unsigned *bits_pos, 
     113                                            const pj_uint8_t **payload, 
     114                                            pj_size_t *payload_len); 
     115 
     116 
     117/** 
     118 * Append an RTP payload to an H.263 picture bitstream. Note that in case of 
     119 * noticing packet lost, application should keep calling this function with 
     120 * payload pointer set to NULL, as the packetizer need to update its internal 
     121 * state. 
     122 * 
     123 * @param pktz          The packetizer. 
     124 * @param payload       The payload to be unpacketized. 
     125 * @param payload_len   The payload length. 
     126 * @param bits          The bitstream buffer. 
     127 * @param bits_size     The bitstream buffer size. 
     128 * @param bits_pos      The bitstream offset to put the unpacketized payload 
     129 *                      in the bitstream, upon return, this will be updated 
     130 *                      to the latest offset as a result of the unpacketized 
     131 *                      payload. 
     132 * 
     133 * @return              PJ_SUCCESS on success. 
     134 */ 
     135PJ_DECL(pj_status_t) pjmedia_h263_unpacketize(pjmedia_h263_packetizer *pktz, 
     136                                              const pj_uint8_t *payload, 
     137                                              pj_size_t payload_len, 
     138                                              pj_uint8_t *bits, 
     139                                              pj_size_t bits_size, 
     140                                              unsigned *bits_pos); 
    140141 
    141142 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/format.h

    r3461 r3493  
    458458{ 
    459459#if PJ_HAS_INT64 
    460     return ((unsigned)((pj_uint64_t)clock_rate * fr->num \ 
    461                        / fr->denum / channel_count)); 
     460    return ((unsigned)((pj_uint64_t)clock_rate * fr->denum \ 
     461                       / fr->num / channel_count)); 
    462462#elif PJ_HAS_FLOATING_POINT 
    463     return ((unsigned)(1.0 * clock_rate * fr->num /fr->denum /channel_count)); 
     463    return ((unsigned)(1.0* clock_rate * fr->denum / fr->num /channel_count)); 
    464464#else 
    465     return ((unsigned)(1L * clock_rate * fr->num / fr->denum / channel_count)); 
     465    return ((unsigned)(1L * clock_rate * fr->denum / fr->num / channel_count)); 
    466466#endif 
    467467} 
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/vid_codec.h

    r3461 r3493  
    224224     * belong to the same picture will share the same RTP timestamp and also 
    225225     * there is marker bit in the RTP header that is usually reserved for 
    226      * end-of-picture flag. 
     226     * end-of-picture flag. Also note that in case of noticing packet lost, 
     227     * application should keep calling this function with payload pointer 
     228     * set to NULL, as the packetizer need to update its internal state. 
    227229     * 
    228230     * @param codec     The codec instance 
     
    242244                               pj_size_t   payload_len, 
    243245                               pj_uint8_t *bits, 
    244                                pj_size_t  *bits_len); 
     246                               pj_size_t   bits_len, 
     247                               unsigned   *bits_pos); 
    245248 
    246249    /**  
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c

    r3469 r3493  
    1919#include <pjmedia-codec/ffmpeg_codecs.h> 
    2020#include <pjmedia-codec/h263_packetizer.h> 
     21#include <pjmedia-codec/h264_packetizer.h> 
    2122#include <pjmedia/errno.h> 
     23#include <pjmedia/vid_codec_util.h> 
    2224#include <pj/assert.h> 
    2325#include <pj/list.h> 
     
    3941#include <libavcodec/avcodec.h> 
    4042#include <libavformat/avformat.h> 
    41 #include <libswscale/swscale.h> 
    42  
    43  
    44 #define PJMEDIA_FORMAT_FFMPEG_UNKNOWN  PJMEDIA_FORMAT_PACK('f','f','0','0'); 
    4543 
    4644 
     
    8078                                       pj_size_t   payload_len, 
    8179                                       pj_uint8_t *buf, 
    82                                        pj_size_t  *buf_len); 
     80                                       pj_size_t   buf_len, 
     81                                       unsigned   *pos); 
    8382static pj_status_t  ffmpeg_codec_encode( pjmedia_vid_codec *codec,  
    8483                                         const pjmedia_frame *input, 
     
    131130typedef struct ffmpeg_codec_desc ffmpeg_codec_desc; 
    132131 
    133 /* ITU resolution ID */ 
    134 typedef 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 */ 
    144 struct 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 }; 
    157132 
    158133/* FFMPEG codecs private data. */ 
    159 typedef struct ffmpeg_private { 
     134typedef struct ffmpeg_private 
     135{ 
    160136    const ffmpeg_codec_desc         *desc; 
    161137    pjmedia_vid_codec_param          param;     /**< Codec param            */ 
     
    180156     */ 
    181157    enum PixelFormat                 expected_dec_fmt; 
    182                                                 /**< expected output format of  
     158                                                /**< Expected output format of  
    183159                                                     ffmpeg decoder         */ 
     160 
     161    void                            *data;      /**< Codec specific data    */               
    184162} ffmpeg_private; 
    185163 
    186164 
    187 typedef pj_status_t (*func_packetize)   (pj_uint8_t *buf, 
    188                                          pj_size_t buf_len, 
    189                                          unsigned *pos, 
    190                                          int max_payload_len, 
    191                                          const pj_uint8_t **payload, 
    192                                          pj_size_t *payload_len); 
    193  
    194 typedef pj_status_t (*func_unpacketize) (const pj_uint8_t *payload, 
    195                                          pj_size_t   payload_len, 
    196                                          pj_uint8_t *bits, 
    197                                          pj_size_t  *bits_len); 
    198  
    199 typedef pj_status_t (*func_parse_fmtp)  (ffmpeg_private *ff); 
     165/* Shortcuts for packetize & unpacketize function declaration, 
     166 * as it has long params and is reused many times! 
     167 */ 
     168#define FUNC_PACKETIZE(name) \ 
     169    pj_status_t(name)(ffmpeg_private *ff, pj_uint8_t *bits, \ 
     170                      pj_size_t bits_len, unsigned *bits_pos, \ 
     171                      const pj_uint8_t **payload, pj_size_t *payload_len) 
     172 
     173#define FUNC_UNPACKETIZE(name) \ 
     174    pj_status_t(name)(ffmpeg_private *ff, const pj_uint8_t *payload, \ 
     175                      pj_size_t payload_len, pj_uint8_t *bits, \ 
     176                      pj_size_t bits_len, unsigned *bits_pos) 
     177 
     178typedef FUNC_PACKETIZE(*func_packetize); 
     179typedef FUNC_UNPACKETIZE(*func_unpacketize); 
     180typedef pj_status_t (*func_preopen)     (ffmpeg_private *ff); 
     181typedef pj_status_t (*func_postopen)    (ffmpeg_private *ff); 
     182 
    200183 
    201184/* FFMPEG codec info */ 
    202 struct ffmpeg_codec_desc { 
     185struct ffmpeg_codec_desc 
     186{ 
    203187    /* Predefined info */ 
    204188    pjmedia_vid_codec_info       info; 
     
    208192    func_packetize               packetize; 
    209193    func_unpacketize             unpacketize; 
    210     func_parse_fmtp              parse_fmtp; 
     194    func_preopen                 preopen; 
     195    func_preopen                 postopen; 
    211196    pjmedia_codec_fmtp           dec_fmtp; 
    212197 
     
    217202}; 
    218203 
    219 /* H263 packetizer */ 
    220 static 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 */ 
    232 static 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 */ 
    241 static pj_status_t h263_parse_fmtp(ffmpeg_private *ff); 
     204 
     205/* Codec specific functions */ 
     206static pj_status_t h264_preopen(ffmpeg_private *ff); 
     207static pj_status_t h264_postopen(ffmpeg_private *ff); 
     208static pj_status_t h263_preopen(ffmpeg_private *ff); 
     209static FUNC_PACKETIZE(h264_packetize); 
     210static FUNC_UNPACKETIZE(h264_unpacketize); 
     211static FUNC_PACKETIZE(h263_packetize); 
     212static FUNC_UNPACKETIZE(h263_unpacketize); 
    242213 
    243214 
     
    245216ffmpeg_codec_desc codec_desc[] = 
    246217{ 
     218    { 
     219        {PJMEDIA_FORMAT_H264,   {"H264",4},         PJMEDIA_RTP_PT_H264}, 
     220        0,      500000,    1000000, 
     221        &h264_packetize, &h264_unpacketize, &h264_preopen, &h264_postopen, 
     222        /* Leading space for better compatibility (strange indeed!) */ 
     223        {2, { {{" profile-level-id",17},    {"42e01e",6}},  
     224              {{" packetization-mode",19},  {"1",1}}, } }, 
     225    }, 
    247226    { 
    248227        {PJMEDIA_FORMAT_H263P,  {"H263-1998",9},    PJMEDIA_RTP_PT_H263P}, 
    249228        PJMEDIA_FORMAT_H263,    1000000,    2000000, 
    250         &h263_packetize, &h263_unpacketize, &h263_parse_fmtp, 
    251         {2, { {{"CIF",3}, {"2",1}}, {{"QCIF",4}, {"1",1}}, } }, 
     229        &h263_packetize, &h263_unpacketize, &h263_preopen, NULL, 
     230        {2, { {{"CIF",3},   {"1",1}},  
     231              {{"QCIF",4},  {"1",1}}, } }, 
    252232    }, 
    253233    { 
    254234        {PJMEDIA_FORMAT_H263,   {"H263",4},         PJMEDIA_RTP_PT_H263}, 
    255     }, 
    256     { 
    257         {PJMEDIA_FORMAT_H264,   {"H264",4},         PJMEDIA_RTP_PT_H264}, 
    258235    }, 
    259236    { 
     
    272249}; 
    273250 
    274 /* Parse fmtp value for custom resolution, e.g: "CUSTOM=800,600,2" */ 
    275 static pj_status_t parse_fmtp_itu_custom_res(const pj_str_t *fmtp_val, 
    276                                              pjmedia_rect_size *size, 
    277                                              unsigned *mpi) 
    278 { 
    279     const char *p, *p_end; 
    280     pj_str_t token; 
    281     unsigned long val[3] = {0}; 
    282     unsigned i = 0; 
    283  
    284     p = token.ptr = fmtp_val->ptr; 
    285     p_end = p + fmtp_val->slen; 
    286  
    287     while (p<=p_end && i<PJ_ARRAY_SIZE(val)) { 
    288         if (*p==',' || p==p_end) { 
    289             token.slen = (char*)p - token.ptr; 
    290             val[i++] = pj_strtoul(&token); 
    291             token.ptr = (char*)p+1; 
     251 
     252typedef struct h264_data 
     253{ 
     254    pjmedia_vid_codec_h264_fmtp  fmtp; 
     255    pjmedia_h264_packetizer     *pktz; 
     256} h264_data; 
     257 
     258 
     259static pj_status_t h264_preopen(ffmpeg_private *ff) 
     260{ 
     261    h264_data *data; 
     262    pjmedia_h264_packetizer_cfg pktz_cfg; 
     263    pj_status_t status; 
     264 
     265    data = PJ_POOL_ZALLOC_T(ff->pool, h264_data); 
     266    ff->data = data; 
     267 
     268    /* Create packetizer */ 
     269    pktz_cfg.mtu = ff->param.enc_mtu; 
     270    pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED; 
     271    status = pjmedia_h264_packetizer_create(ff->pool, &pktz_cfg, &data->pktz); 
     272    if (status != PJ_SUCCESS) 
     273        return status; 
     274 
     275    if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 
     276        AVCodecContext *ctx = ff->enc_ctx; 
     277 
     278        status = pjmedia_vid_codec_parse_h264_fmtp(&ff->param.enc_fmtp, 
     279                                                   &data->fmtp); 
     280        if (status != PJ_SUCCESS) 
     281            return status; 
     282 
     283        ctx->profile  = data->fmtp.profile_idc; 
     284        if (data->fmtp.profile_iop) { 
     285#if defined(FF_PROFILE_H264_CONSTRAINED) 
     286            ctx->profile |= FF_PROFILE_H264_CONSTRAINED; 
     287#endif 
    292288        } 
    293         ++p; 
    294     } 
    295  
    296     if (!val[0] || !val[1]) 
    297         return PJ_ETOOSMALL; 
    298  
    299     if (val[2]<1 || val[2]>32) 
    300         return PJ_EINVAL; 
    301  
    302     size->w = val[0]; 
    303     size->h = val[1]; 
    304     *mpi = val[2]; 
    305     return PJ_SUCCESS; 
    306 } 
    307  
    308 #define CALC_ITU_CUSTOM_RES_SCORE(size, mpi) ((size)->w * (size)->h / mpi) 
    309  
    310 /* ITU codec capabilities */ 
    311 typedef struct itu_cap 
    312 { 
    313     /* Lowest MPI for each non-custom resolution */ 
    314     unsigned            lowest_mpi[PJ_ARRAY_SIZE(itu_res_def)]; 
    315     /* For custom resolution, we use maximum processing score */ 
    316     unsigned            custom_res_max_score; 
    317 } itu_cap; 
    318  
    319  
    320 static pj_status_t load_itu_cap(const pjmedia_codec_fmtp *fmtp, 
    321                                 itu_cap *cap) 
    322 { 
    323     unsigned i, j; 
    324     unsigned min_mpi = 0; 
    325  
    326     /* Get Minimum Picture Interval (MPI) for each resolution. If a resolution 
    327      * has no MPI setting in fmtp, the MPI setting is derived from the higher 
    328      * resolution. 
    329      */ 
    330     for (i=0; i<PJ_ARRAY_SIZE(itu_res_def); ++i) { 
    331  
    332         /* Init lowest MPI */ 
    333         cap->lowest_mpi[i] = min_mpi? min_mpi:1; 
    334  
    335         for (j=0; j<fmtp->cnt; ++j) { 
    336             if (pj_stricmp(&fmtp->param[j].name, &itu_res_def[i].name)==0) { 
    337                 pjmedia_rect_size size; 
    338                 unsigned mpi; 
    339                 unsigned score; 
    340  
    341                 if (i != ITU_RES_CUSTOM) { 
    342                     size = itu_res_def[i].size; 
    343                     mpi = pj_strtoul(&fmtp->param[j].val); 
    344                     if (min_mpi) 
    345                         min_mpi = PJ_MIN(mpi, min_mpi); 
    346                     else 
    347                         min_mpi = mpi; 
    348  
    349                     /* Update the lowest MPI for this resolution */ 
    350                     cap->lowest_mpi[i] = min_mpi; 
    351  
    352                     /* Also update the processing score for the custom  
    353                      * resolution. 
    354                      */ 
    355                     score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 
    356                     cap->custom_res_max_score =  
    357                                     PJ_MAX(score, cap->custom_res_max_score); 
    358                 } else { 
    359                      
    360  
    361                     if (parse_fmtp_itu_custom_res(&fmtp->param[j].val,  
    362                                                   &size, &mpi) == PJ_SUCCESS) 
    363                     { 
    364                         score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 
    365                         cap->custom_res_max_score =  
    366                                     PJ_MAX(score, cap->custom_res_max_score); 
    367                     } 
    368                 } 
    369             } 
    370         } 
    371     } 
    372  
    373     return PJ_SUCCESS; 
    374 } 
    375  
    376 /* H263 fmtp parser */ 
    377 static pj_status_t h263_parse_fmtp(ffmpeg_private *ff) 
    378 { 
    379     pjmedia_dir dir; 
     289        ctx->level    = data->fmtp.level; 
     290        PJ_TODO(set_h264_constrain_bits_properly_in_ffmpeg); 
     291 
     292        /* Libx264 rejects the "broken" ffmpeg defaults, so just change some */ 
     293        ctx->me_range = 16; 
     294        ctx->max_qdiff = 4; 
     295        ctx->qmin = 10; 
     296        ctx->qmax = 51; 
     297        ctx->qcompress = 0.6f; 
     298 
     299        ctx->flags |= CODEC_FLAG_LOW_DELAY; 
     300    } 
     301 
     302    return PJ_SUCCESS; 
     303} 
     304 
     305static pj_status_t h264_postopen(ffmpeg_private *ff) 
     306{ 
     307    h264_data *data = (h264_data*)ff->data; 
     308    PJ_UNUSED_ARG(data); 
     309 
     310    // Where to apply the "sprop-parameter-sets" fmtp from remote SDP? 
     311    // Through decoder decode() or decoder context extradata? 
     312    PJ_TODO(apply_h264_fmtp_sprop_parameter_sets_from_remote_sdp); 
     313 
     314    return PJ_SUCCESS; 
     315} 
     316 
     317 
     318static FUNC_PACKETIZE(h264_packetize) 
     319{ 
     320    h264_data *data = (h264_data*)ff->data; 
     321    return pjmedia_h264_packetize(data->pktz, bits, bits_len, bits_pos, 
     322                                  payload, payload_len); 
     323} 
     324 
     325static FUNC_UNPACKETIZE(h264_unpacketize) 
     326{ 
     327    h264_data *data = (h264_data*)ff->data; 
     328    return pjmedia_h264_unpacketize(data->pktz, payload, payload_len, 
     329                                    bits, bits_len, bits_pos); 
     330} 
     331 
     332 
     333typedef struct h263_data 
     334{ 
     335    pjmedia_h263_packetizer     *pktz; 
     336} h263_data; 
     337 
     338/* H263 pre-open */ 
     339static pj_status_t h263_preopen(ffmpeg_private *ff) 
     340{ 
     341    h263_data *data; 
     342    pjmedia_h263_packetizer_cfg pktz_cfg; 
    380343    pj_status_t status; 
    381344 
    382     dir = ff->param.dir; 
    383  
    384     if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 
    385         pjmedia_vid_codec_param param_ref; 
    386         pjmedia_codec_fmtp *fmtp_rem, *fmtp_ref; 
    387         itu_cap local_cap; 
    388         pjmedia_rect_size size = {0}; 
    389         unsigned mpi = 0; 
    390         pj_bool_t got_good_res = PJ_FALSE; 
    391         pj_bool_t has_prefered_res = PJ_FALSE; 
    392         unsigned i, j; 
    393  
    394         fmtp_rem = &ff->param.enc_fmtp; 
    395         dir &= ~PJMEDIA_DIR_ENCODING; 
    396  
    397         /* Get default fmtp setting as the reference for local capabilities */ 
    398         status = pjmedia_vid_codec_mgr_get_default_param( 
    399                         ffmpeg_factory.mgr, &ff->desc->info, &param_ref); 
    400         fmtp_ref = (status==PJ_SUCCESS)? &param_ref.enc_fmtp : fmtp_rem; 
    401  
    402         /* Load default local capabilities */ 
    403         status = load_itu_cap(fmtp_ref, &local_cap); 
    404         pj_assert(status == PJ_SUCCESS); 
    405  
    406         /* Negotiate resolution and MPI */ 
    407         for (i=0; i<fmtp_rem->cnt && !got_good_res; ++i) 
    408         { 
    409             for (j=0; j<PJ_ARRAY_SIZE(itu_res_def) && !got_good_res; ++j) 
    410             { 
    411                 if (pj_stricmp(&fmtp_rem->param[i].name, &itu_res_def[j].name)) 
    412                     continue; 
    413  
    414                 has_prefered_res = PJ_TRUE; 
    415                 if (j == ITU_RES_CUSTOM) { 
    416                     unsigned score; 
    417  
    418                     if (parse_fmtp_itu_custom_res(&fmtp_rem->param[i].val,  
    419                                                   &size, &mpi) != PJ_SUCCESS) 
    420                     { 
    421                         /* Invalid custom resolution format, skip this  
    422                          * custom resolution 
    423                          */ 
    424                         break; 
    425                     } 
    426  
    427                     score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 
    428                     if (score <= local_cap.custom_res_max_score) 
    429                         got_good_res = PJ_TRUE; 
    430                 } else { 
    431                     mpi = pj_strtoul(&fmtp_rem->param[i].val); 
    432                     if (mpi>=1 && mpi<=32 && mpi>=local_cap.lowest_mpi[j]) { 
    433                         got_good_res = PJ_TRUE; 
    434                         size = itu_res_def[j].size; 
    435                     } 
    436                 } 
    437             } 
    438         } 
    439  
    440         if (has_prefered_res) { 
    441             if (got_good_res) { 
    442                 pjmedia_video_format_detail *vfd; 
    443  
    444                 /* Apply this size & MPI */ 
    445                 vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, 
    446                                                              PJ_TRUE); 
    447                 vfd->size = size; 
    448                 vfd->fps.num = 30000; 
    449                 vfd->fps.denum = 1001 * mpi; 
    450                 got_good_res = PJ_TRUE; 
    451  
    452                 PJ_TODO(NOTIFY_APP_ABOUT_THIS_NEW_ENCODING_FORMAT); 
    453             } else { 
    454                 return PJMEDIA_EBADFMT; 
    455             } 
    456         } 
    457     } 
    458  
    459     return PJ_SUCCESS; 
    460 } 
    461  
     345    data = PJ_POOL_ZALLOC_T(ff->pool, h263_data); 
     346    ff->data = data; 
     347 
     348    /* Create packetizer */ 
     349    pktz_cfg.mtu = ff->param.enc_mtu; 
     350    pktz_cfg.mode = PJMEDIA_H263_PACKETIZER_MODE_RFC4629; 
     351    status = pjmedia_h263_packetizer_create(ff->pool, &pktz_cfg, &data->pktz); 
     352    if (status != PJ_SUCCESS) 
     353        return status; 
     354 
     355    /* Apply fmtp settings to codec param */ 
     356    status = pjmedia_vid_codec_h263_apply_fmtp(&ff->param); 
     357 
     358    return status; 
     359} 
     360 
     361static FUNC_PACKETIZE(h263_packetize) 
     362{ 
     363    h263_data *data = (h263_data*)ff->data; 
     364    return pjmedia_h263_packetize(data->pktz, bits, bits_len, bits_pos, 
     365                                  payload, payload_len); 
     366} 
     367 
     368static FUNC_UNPACKETIZE(h263_unpacketize) 
     369{ 
     370    h263_data *data = (h263_data*)ff->data; 
     371    return pjmedia_h263_unpacketize(data->pktz, payload, payload_len, 
     372                                    bits, bits_len, bits_pos); 
     373} 
    462374 
    463375 
     
    810722    attr->enc_fmt.det.vid.max_bps = desc->max_bps; 
    811723 
     724    /* MTU */ 
     725    attr->enc_mtu = PJMEDIA_MAX_MTU; 
     726 
    812727    return PJ_SUCCESS; 
    813728} 
     
    934849 
    935850static enum PixelFormat dec_get_format(struct AVCodecContext *s,  
    936                                           const enum PixelFormat * fmt) 
     851                                       const enum PixelFormat * fmt) 
    937852{ 
    938853    ffmpeg_private *ff = (ffmpeg_private*)s->opaque; 
     
    954869{ 
    955870    enum PixelFormat pix_fmt; 
     871    pjmedia_video_format_detail *vfd; 
     872    pj_bool_t enc_opened = PJ_FALSE, dec_opened = PJ_FALSE; 
    956873    pj_status_t status; 
    957     pjmedia_video_format_detail *vfd; 
    958  
     874 
     875    /* Get decoded pixel format */ 
    959876    status = pjmedia_format_id_to_PixelFormat(ff->param.dec_fmt.id, 
    960877                                              &pix_fmt); 
    961878    if (status != PJ_SUCCESS) 
    962879        return status; 
    963  
     880    ff->expected_dec_fmt = pix_fmt; 
     881 
     882    /* Get video format detail for shortcut access to encoded format */ 
    964883    vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt,  
    965884                                                 PJ_TRUE); 
    966     ff->expected_dec_fmt = pix_fmt; 
    967  
    968     while (((ff->param.dir & PJMEDIA_DIR_ENCODING) && ff->enc_ctx == NULL) || 
    969            ((ff->param.dir & PJMEDIA_DIR_DECODING) && ff->dec_ctx == NULL)) 
    970     { 
    971         pjmedia_dir dir; 
    972         AVCodecContext *ctx = NULL; 
    973         AVCodec *codec = NULL; 
     885 
     886    /* Allocate ffmpeg codec context */ 
     887    if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 
     888        ff->enc_ctx = avcodec_alloc_context(); 
     889        if (ff->enc_ctx == NULL) 
     890            goto on_error; 
     891    } 
     892    if (ff->param.dir & PJMEDIA_DIR_DECODING) { 
     893        ff->dec_ctx = avcodec_alloc_context(); 
     894        if (ff->dec_ctx == NULL) 
     895            goto on_error; 
     896    } 
     897 
     898    /* Let the codec apply specific settings before the codec opened */ 
     899    if (ff->desc->preopen) { 
     900        status = (*ff->desc->preopen)(ff); 
     901        if (status != PJ_SUCCESS) 
     902            goto on_error; 
     903    } 
     904 
     905    if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 
     906        AVCodecContext *ctx = ff->enc_ctx; 
    974907        int err; 
    975908 
    976         /* Set which direction to open */ 
    977         if (ff->param.dir==PJMEDIA_DIR_ENCODING_DECODING && ff->enc!=ff->dec) { 
    978             dir = ff->enc_ctx? PJMEDIA_DIR_DECODING : PJMEDIA_DIR_ENCODING; 
    979         } else { 
    980             dir = ff->param.dir; 
    981         } 
    982  
    983         /* Init ffmpeg codec context */ 
    984         ctx = avcodec_alloc_context(); 
    985  
    986         /* Common attributes */ 
     909        /* Init common settings */ 
    987910        ctx->pix_fmt = pix_fmt; 
     911        ctx->width = vfd->size.w; 
     912        ctx->height = vfd->size.h; 
     913        ctx->time_base.num = vfd->fps.denum; 
     914        ctx->time_base.den = vfd->fps.num; 
     915        if (vfd->avg_bps) { 
     916            ctx->bit_rate = vfd->avg_bps; 
     917            if (vfd->max_bps > vfd->avg_bps) 
     918                ctx->bit_rate_tolerance = vfd->max_bps - vfd->avg_bps; 
     919        } 
     920        ctx->strict_std_compliance = FF_COMPLIANCE_STRICT; 
    988921        ctx->workaround_bugs = FF_BUG_AUTODETECT; 
    989922        ctx->opaque = ff; 
    990923 
    991         if (dir & PJMEDIA_DIR_ENCODING) { 
    992             codec = ff->enc; 
    993  
    994             /* Encoding only attributes */ 
    995             ctx->width = vfd->size.w; 
    996             ctx->height = vfd->size.h; 
    997             ctx->time_base.num = vfd->fps.denum; 
    998             ctx->time_base.den = vfd->fps.num; 
    999             if (vfd->avg_bps) { 
    1000                 ctx->bit_rate = vfd->avg_bps; 
    1001                 if (vfd->max_bps > vfd->avg_bps) 
    1002                     ctx->bit_rate_tolerance = vfd->max_bps - vfd->avg_bps; 
    1003             } 
    1004  
    1005             /* Libx264 experimental setting (it rejects ffmpeg defaults) */ 
    1006             if (ff->param.enc_fmt.id == PJMEDIA_FORMAT_H264) { 
    1007                 ctx->me_range = 16; 
    1008                 ctx->max_qdiff = 4; 
    1009                 ctx->qmin = 10; 
    1010                 ctx->qmax = 51; 
    1011                 ctx->qcompress = 0.6f; 
    1012             } 
    1013  
    1014             /* For encoder, should be better to be strict to the standards */ 
    1015             ctx->strict_std_compliance = FF_COMPLIANCE_STRICT; 
    1016         } 
    1017  
    1018         if (dir & PJMEDIA_DIR_DECODING) { 
    1019             codec = ff->dec; 
    1020  
    1021             /* Decoding only attributes */ 
    1022  
    1023             /* Width/height may be overriden by ffmpeg after first decoding. */ 
    1024             ctx->width = ctx->coded_width = ff->param.dec_fmt.det.vid.size.w; 
    1025             ctx->height = ctx->coded_height = ff->param.dec_fmt.det.vid.size.h; 
    1026  
    1027             /* For decoder, be more flexible */ 
    1028             if (ff->param.dir!=PJMEDIA_DIR_ENCODING_DECODING ||  
    1029                 ff->enc!=ff->dec) 
    1030             { 
    1031                 ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; 
    1032             } 
    1033  
    1034             ctx->get_format = &dec_get_format; 
    1035         } 
    1036  
    1037         /* avcodec_open() should be protected */ 
     924        /* Open ffmpeg codec */ 
    1038925        pj_mutex_lock(ff_mutex); 
    1039         err = avcodec_open(ctx, codec); 
     926        err = avcodec_open(ctx, ff->enc); 
    1040927        pj_mutex_unlock(ff_mutex); 
    1041928        if (err < 0) { 
    1042929            print_ffmpeg_err(err); 
    1043             return PJMEDIA_CODEC_EFAILED; 
     930            status = PJMEDIA_CODEC_EFAILED; 
     931            goto on_error; 
    1044932        } 
    1045  
    1046         if (dir & PJMEDIA_DIR_ENCODING) 
    1047             ff->enc_ctx = ctx; 
    1048         if (dir & PJMEDIA_DIR_DECODING) 
    1049             ff->dec_ctx = ctx; 
    1050     } 
    1051      
    1052     return PJ_SUCCESS; 
     933        enc_opened = PJ_TRUE; 
     934    } 
     935 
     936    if (ff->param.dir & PJMEDIA_DIR_DECODING) { 
     937        AVCodecContext *ctx = ff->dec_ctx; 
     938        int err; 
     939 
     940        /* Init common settings */ 
     941        /* Width/height may be overriden by ffmpeg after first decoding. */ 
     942        ctx->width  = ctx->coded_width  = ff->param.dec_fmt.det.vid.size.w; 
     943        ctx->height = ctx->coded_height = ff->param.dec_fmt.det.vid.size.h; 
     944        ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; 
     945        ctx->workaround_bugs = FF_BUG_AUTODETECT; 
     946        ctx->opaque = ff; 
     947        ctx->get_format = &dec_get_format; 
     948 
     949        /* Open ffmpeg codec */ 
     950        pj_mutex_lock(ff_mutex); 
     951        err = avcodec_open(ctx, ff->dec); 
     952        pj_mutex_unlock(ff_mutex); 
     953        if (err < 0) { 
     954            print_ffmpeg_err(err); 
     955            status = PJMEDIA_CODEC_EFAILED; 
     956            goto on_error; 
     957        } 
     958        dec_opened = PJ_TRUE; 
     959    } 
     960 
     961    /* Let the codec apply specific settings after the codec opened */ 
     962    if (ff->desc->postopen) { 
     963        status = (*ff->desc->postopen)(ff); 
     964        if (status != PJ_SUCCESS) 
     965            goto on_error; 
     966    } 
     967 
     968    return PJ_SUCCESS; 
     969 
     970on_error: 
     971    if (ff->enc_ctx) { 
     972        if (enc_opened) 
     973            avcodec_close(ff->enc_ctx); 
     974        av_free(ff->enc_ctx); 
     975        ff->enc_ctx = NULL; 
     976    } 
     977    if (ff->dec_ctx) { 
     978        if (dec_opened) 
     979            avcodec_close(ff->dec_ctx); 
     980        av_free(ff->dec_ctx); 
     981        ff->dec_ctx = NULL; 
     982    } 
     983    return status; 
    1053984} 
    1054985 
     
    1067998 
    1068999    pj_memcpy(&ff->param, attr, sizeof(*attr)); 
    1069  
    1070     /* Apply SDP fmtp attribute */ 
    1071     if (ff->desc->parse_fmtp) { 
    1072         status = (*ff->desc->parse_fmtp)(ff); 
    1073         if (status != PJ_SUCCESS) 
    1074             goto on_error; 
    1075     } 
    10761000 
    10771001    /* Open the codec */ 
     
    11791103 
    11801104static pj_status_t  ffmpeg_packetize ( pjmedia_vid_codec *codec, 
    1181                                        pj_uint8_t *buf, 
    1182                                        pj_size_t buf_len, 
    1183                                        unsigned *pos, 
     1105                                       pj_uint8_t *bits, 
     1106                                       pj_size_t bits_len, 
     1107                                       unsigned *bits_pos, 
    11841108                                       const pj_uint8_t **payload, 
    11851109                                       pj_size_t *payload_len) 
     
    11881112 
    11891113    if (ff->desc->packetize) { 
    1190         return (*ff->desc->packetize)(buf, buf_len, pos, 
    1191                                       ff->param.enc_mtu, payload, 
    1192                                       payload_len); 
     1114        return (*ff->desc->packetize)(ff, bits, bits_len, bits_pos, 
     1115                                      payload, payload_len); 
    11931116    } 
    11941117 
     
    11991122                                       const pj_uint8_t *payload, 
    12001123                                       pj_size_t   payload_len, 
    1201                                        pj_uint8_t *buf, 
    1202                                        pj_size_t  *buf_len) 
     1124                                       pj_uint8_t *bits, 
     1125                                       pj_size_t   bits_len, 
     1126                                       unsigned   *bits_pos) 
    12031127{ 
    12041128    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
    12051129 
    12061130    if (ff->desc->unpacketize) { 
    1207         return (*ff->desc->unpacketize)(payload, payload_len, 
    1208                                         buf, buf_len); 
     1131        return (*ff->desc->unpacketize)(ff, payload, payload_len, 
     1132                                        bits, bits_len, bits_pos); 
    12091133    } 
    12101134     
     
    12271151    int out_buf_len = output_buf_len; 
    12281152    int err; 
    1229  
     1153    AVRational src_timebase; 
    12301154    /* For some reasons (e.g: SSE/MMX usage), the avcodec_encode_video() must 
    12311155     * have stack aligned to 16 bytes. Let's try to be safe by preparing the 
     
    12341158    PJ_ALIGN_DATA(pj_uint32_t i[4], 16); 
    12351159 
     1160    if ((long)i & 0xF) { 
     1161        PJ_LOG(2,(THIS_FILE, "Stack alignment fails")); 
     1162    } 
     1163 
    12361164    /* Check if encoder has been opened */ 
    12371165    PJ_ASSERT_RETURN(ff->enc_ctx, PJ_EINVALIDOP); 
    12381166 
    12391167    avcodec_get_frame_defaults(&avframe); 
    1240     avframe.pts = input->timestamp.u64; 
     1168    src_timebase.num = 1; 
     1169    src_timebase.den = ff->desc->info.clock_rate; 
     1170    avframe.pts = av_rescale_q(input->timestamp.u64, src_timebase, 
     1171                               ff->enc_ctx->time_base); 
    12411172     
    12421173    for (i[0] = 0; i[0] < ff->enc_vfi->plane_cnt; ++i[0]) { 
     
    13041235 
    13051236#if LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72 
    1306     avpacket.flags = AV_PKT_FLAG_KEY; 
     1237    //avpacket.flags = AV_PKT_FLAG_KEY; 
    13071238#else 
    13081239    avpacket.flags = 0; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/sdp_neg.c

    r3347 r3493  
    5353}; 
    5454 
    55 #define GET_FMTP_IVAL(ival, fmtp, param, default_val) \ 
     55#define GET_FMTP_IVAL_BASE(ival, base, fmtp, param, default_val) \ 
    5656    do { \ 
    5757        pj_str_t s; \ 
     
    6464        pj_strset(&s, p + param.slen, fmtp.fmt_param.slen - \ 
    6565                  (p - fmtp.fmt_param.ptr) - param.slen); \ 
    66         ival = pj_strtoul(&s); \ 
     66        ival = pj_strtoul2(&s, NULL, base); \ 
    6767    } while (0) 
     68 
     69#define GET_FMTP_IVAL(ival, fmtp, param, default_val) \ 
     70        GET_FMTP_IVAL_BASE(ival, 10, fmtp, param, default_val) 
     71 
    6872 
    6973/* 
     
    679683 
    680684 
     685/* Matching H.264 between offer and answer. */ 
     686static pj_bool_t match_h264( const pjmedia_sdp_media *offer, 
     687                             unsigned o_fmt_idx, 
     688                             const pjmedia_sdp_media *answer, 
     689                             unsigned a_fmt_idx) 
     690{ 
     691    const pjmedia_sdp_attr *attr_ans; 
     692    const pjmedia_sdp_attr *attr_ofr; 
     693    pjmedia_sdp_fmtp fmtp; 
     694    pj_uint32_t profile1, profile2; 
     695    unsigned pack_mode1, pack_mode2; 
     696    const pj_str_t STR_PROFILE   = {"profile-level-id=", 17}; 
     697    const pj_str_t STR_PACK_MODE = {"packetization-mode=", 19}; 
     698 
     699    /* Parse offer */ 
     700    attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp",  
     701                                            &offer->desc.fmt[o_fmt_idx]); 
     702    if (!attr_ofr) 
     703        return PJ_FALSE; 
     704 
     705    if (pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp) != PJ_SUCCESS) 
     706        return PJ_FALSE; 
     707 
     708    GET_FMTP_IVAL_BASE(profile1, 16, fmtp, STR_PROFILE, 0x42000A); 
     709    GET_FMTP_IVAL(pack_mode1, fmtp, STR_PACK_MODE, 0); 
     710 
     711    /* Parse answer */ 
     712    attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp",  
     713                                            &answer->desc.fmt[a_fmt_idx]); 
     714    if (!attr_ans) 
     715        return PJ_FALSE; 
     716 
     717    if (pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp) != PJ_SUCCESS) 
     718        return PJ_FALSE; 
     719 
     720    GET_FMTP_IVAL_BASE(profile2, 16, fmtp, STR_PROFILE, 0x42000A); 
     721    GET_FMTP_IVAL(pack_mode2, fmtp, STR_PACK_MODE, 0); 
     722 
     723    /* Compare bitrate in answer and offer. */ 
     724    return ((profile1 == profile2) && (pack_mode1 == pack_mode2)); 
     725} 
     726 
     727 
    681728/* Toggle AMR octet-align setting in the fmtp. 
    682729 */ 
     
    877924                        { 
    878925                            /* Further check for G7221, negotiate bitrate. */ 
    879                             if (pj_stricmp2(&or_.enc_name, "G7221") == 0) { 
     926                            if (pj_stricmp2(&or_.enc_name, "G7221") == 0) 
     927                            { 
    880928                                if (match_g7221(offer, i, answer, j)) 
    881929                                    break; 
     
    887935                                if (match_amr(offer, i, answer, j, PJ_FALSE,  
    888936                                              NULL)) 
     937                                    break; 
     938                            } else 
     939                            /* Further check for H264, negotiate fmtp. */ 
     940                            if (pj_stricmp2(&or_.enc_name, "H264") == 0) 
     941                            { 
     942                                if (match_h264(offer, i, answer, j)) 
    889943                                    break; 
    890944                            } else { 
     
    12001254                                                   PJ_TRUE, &pt_amr_need_adapt)) 
    12011255                                        continue; 
     1256                                } else 
     1257                                if (pj_stricmp2(&or_.enc_name, "H264") == 0 && 
     1258                                    !match_h264(master, i, slave, j)) 
     1259                                { 
     1260                                    continue; 
    12021261                                } 
    12031262                                found_matching_codec = 1; 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_stream.c

    r3461 r3493  
    769769        LOGERR_((channel->port.info.name.ptr,  
    770770                "Codec encode() error", status)); 
     771 
     772        /* Update RTP timestamp */ 
     773        pjmedia_rtp_encode_rtp(&channel->rtp, channel->pt, 1, 0, 
     774                               rtp_ts_len, &rtphdr, &rtphdrlen); 
    771775        return status; 
    772776    } 
     
    789793            LOGERR_((channel->port.info.name.ptr,  
    790794                    "Codec pack() error", status)); 
     795 
     796            /* Update RTP timestamp */ 
     797            pjmedia_rtp_encode_rtp(&channel->rtp, channel->pt, 1, 0, 
     798                                   rtp_ts_len, &rtphdr, &rtphdrlen); 
    791799            return status; 
    792800        } 
     
    867875     */ 
    868876    { 
    869         pj_uint8_t *p, *data; 
    870         char ptype; 
    871         pj_size_t psize, data_len; 
    872         pj_uint32_t ts; 
    873         int seq; 
    874877        pj_bool_t got_frame; 
    875         unsigned i; 
     878        unsigned cnt; 
    876879 
    877880        channel->buf_len = 0; 
     
    881884        pj_mutex_lock( stream->jb_mutex ); 
    882885 
    883         for (i=0; ; ++i) { 
    884             /* Get frame from jitter buffer. */ 
    885             pjmedia_jbuf_peek_frame(stream->jb, i, (const void**)&p, 
    886                                     &psize, &ptype, NULL, &ts, &seq); 
     886        /* Check if we got a decodable frame */ 
     887        for (cnt=0; ; ++cnt) { 
     888            char ptype; 
     889            pj_uint32_t ts; 
     890            int seq; 
     891 
     892            /* Peek frame from jitter buffer. */ 
     893            pjmedia_jbuf_peek_frame(stream->jb, cnt, NULL, NULL, 
     894                                    &ptype, NULL, &ts, &seq); 
    887895            if (ptype == PJMEDIA_JB_NORMAL_FRAME) { 
    888896                if (last_ts == 0) { 
     
    890898                    frm_first_seq = seq; 
    891899                } 
    892  
    893900                if (ts != last_ts) { 
    894901                    got_frame = PJ_TRUE; 
    895                     pjmedia_jbuf_remove_frame(stream->jb, i); 
    896902                    break; 
    897903                } 
    898  
    899                 data = (pj_uint8_t*)channel->buf + channel->buf_len; 
    900                 data_len = channel->buf_size - channel->buf_len; 
    901                 status = (*stream->codec->op->unpacketize)(stream->codec, 
    902                                                            p, psize, 
    903                                                            data, &data_len); 
    904                 channel->buf_len += data_len; 
    905904                frm_last_seq = seq; 
    906905            } else if (ptype == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 
     
    908907                break; 
    909908            } 
     909        } 
     910 
     911        if (got_frame) { 
     912            unsigned i; 
     913 
     914            /* Generate frame bitstream from the payload */ 
     915            channel->buf_len = 0; 
     916            for (i = 0; i < cnt; ++i) { 
     917                const pj_uint8_t *p; 
     918                pj_size_t psize; 
     919                char ptype; 
     920 
     921                /* We use jbuf_peek_frame() as it will returns the pointer of 
     922                 * the payload (no buffer and memcpy needed), just as we need. 
     923                 */ 
     924                pjmedia_jbuf_peek_frame(stream->jb, i, &p, 
     925                                        &psize, &ptype, NULL, NULL, NULL); 
     926 
     927                if (ptype != PJMEDIA_JB_NORMAL_FRAME) { 
     928                    /* Packet lost, must set payload to NULL and keep going */ 
     929                    p = NULL; 
     930                    psize = 0; 
     931                } 
     932 
     933                status = (*stream->codec->op->unpacketize)( 
     934                                                stream->codec, 
     935                                                p, psize, 
     936                                                (pj_uint8_t*)channel->buf, 
     937                                                channel->buf_size, 
     938                                                &channel->buf_len); 
     939                if (status != PJ_SUCCESS) { 
     940                    LOGERR_((channel->port.info.name.ptr,  
     941                            "Codec unpack() error", status)); 
     942                    /* Just ignore this unpack error */ 
     943                } 
     944            } 
     945 
     946            pjmedia_jbuf_remove_frame(stream->jb, cnt); 
    910947        } 
    911948 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/test/vid_codec_test.c

    r3425 r3493  
    77#define THIS_FILE "vid_codec.c" 
    88 
    9 #define BYPASS_CODEC 0 
     9#define BYPASS_CODEC        0 
     10#define BYPASS_PACKETIZER   0 
    1011 
    1112typedef struct codec_port_data_t 
     
    1516    pj_uint8_t          *enc_buf; 
    1617    pj_size_t            enc_buf_size; 
     18    pj_uint8_t          *pack_buf; 
     19    pj_size_t            pack_buf_size; 
    1720} codec_port_data_t; 
    1821 
     
    3336        status = codec->op->encode(codec, frame, enc_frame.size, &enc_frame); 
    3437        if (status != PJ_SUCCESS) goto on_error; 
     38 
     39#if !BYPASS_PACKETIZER 
     40        if (enc_frame.size) { 
     41            unsigned pos = 0, i = 0; 
     42            pj_bool_t packetized = PJ_FALSE; 
     43            unsigned unpack_pos = 0; 
     44             
     45            while (pos < enc_frame.size) { 
     46                pj_uint8_t *payload; 
     47                pj_size_t payload_len; 
     48 
     49                status = codec->op->packetize(codec,  
     50                                              (pj_uint8_t*)enc_frame.buf, 
     51                                              enc_frame.size, &pos, 
     52                                              &payload, &payload_len); 
     53                if (status == PJ_ENOTSUP) 
     54                    break; 
     55                if (status != PJ_SUCCESS) 
     56                    goto on_error; 
     57 
     58                status = codec->op->unpacketize(codec, payload, payload_len, 
     59                                                port_data->pack_buf, 
     60                                                port_data->pack_buf_size, 
     61                                                &unpack_pos); 
     62                if (status != PJ_SUCCESS) 
     63                    goto on_error; 
     64 
     65                // what happen if the bitstream is broken? 
     66                //if (i++ != 1) unpack_pos -= 10; 
     67 
     68                packetized = PJ_TRUE; 
     69            } 
     70 
     71            if (packetized) { 
     72                enc_frame.buf  = port_data->pack_buf; 
     73                enc_frame.size = unpack_pos; 
     74            } 
     75        } 
     76#endif 
     77 
    3578        status = codec->op->decode(codec, &enc_frame, frame->size, frame); 
    3679        if (status != PJ_SUCCESS) goto on_error; 
     
    78121 
    79122    for (i = 0; i < cnt; ++i) { 
    80         PJ_LOG(3, (THIS_FILE, "  %16.*s %c%c %s", 
     123        PJ_LOG(3, (THIS_FILE, "  %-16.*s %c%c %s", 
    81124                   info[i].encoding_name.slen, info[i].encoding_name.ptr, 
    82125                   (info[i].dir & PJMEDIA_DIR_ENCODING? 'E' : ' '), 
     
    123166    } 
    124167 
     168 
    125169    /* Lookup colorbar source */ 
    126170    status = pjmedia_vid_dev_lookup("Colorbar", "Colorbar generator", &cap_idx); 
     
    135179    } 
    136180 
     181    raw_fmt_id = codec_info->dec_fmt_id[0]; 
     182    cap_idx = 0; /* Use dshow capture */ 
     183 
     184#if 0 
     185    // Now, the video port can do automatic conversion. 
    137186    /* Raw format ID "not specified", lets find common format among the codec 
    138187     * and the video devices 
     
    166215        } 
    167216    } 
     217#endif 
    168218 
    169219    /* Prepare codec */ 
     
    265315    codec_port_data.enc_buf = pj_pool_alloc(pool,  
    266316                                            codec_port_data.enc_buf_size); 
     317    codec_port_data.pack_buf_size = codec_port_data.enc_buf_size; 
     318    codec_port_data.pack_buf = pj_pool_alloc(pool,  
     319                                             codec_port_data.pack_buf_size); 
    267320 
    268321    codec_port.put_frame = &codec_put_frame; 
Note: See TracChangeset for help on using the changeset viewer.