Changeset 3493
- Timestamp:
- Mar 31, 2011 5:29:54 PM (14 years ago)
- 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 67 67 stream_common.o stream.o tonegen.o transport_adapter_sample.o \ 68 68 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 \ 70 71 wav_player.o wav_playlist.o wav_writer.o wave.o \ 71 72 wsola.o … … 110 111 export PJMEDIA_CODEC_SRCDIR = ../src/pjmedia-codec 111 112 export PJMEDIA_CODEC_OBJS += ffmpeg_codecs.o \ 113 h263_packetizer.o h264_packetizer.o \ 112 114 $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ 113 115 ipp_codecs.o $(CODEC_OBJS) -
pjproject/branches/projects/2.0-dev/pjmedia/build/pjmedia.vcproj
r3420 r3493 4693 4693 </File> 4694 4694 <File 4695 RelativePath="..\src\pjmedia\vid_codec_util.c" 4696 > 4697 </File> 4698 <File 4695 4699 RelativePath="..\src\pjmedia\vid_stream.c" 4696 4700 > … … 5134 5138 </File> 5135 5139 <File 5140 RelativePath="..\include\pjmedia\vid_codec_util.h" 5141 > 5142 </File> 5143 <File 5136 5144 RelativePath="..\include\pjmedia\vid_stream.h" 5137 5145 > -
pjproject/branches/projects/2.0-dev/pjmedia/build/pjmedia_codec.vcproj
r3394 r3493 2834 2834 /> 2835 2835 </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 > 2836 2844 </File> 2837 2845 <File … … 3071 3079 </File> 3072 3080 <File 3081 RelativePath="..\include\pjmedia-codec\h264_packetizer.h" 3082 > 3083 </File> 3084 <File 3073 3085 RelativePath="..\include\pjmedia-codec\ilbc.h" 3074 3086 > -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-codec/h263_packetizer.h
r3486 r3493 23 23 /** 24 24 * @file h263_packetizer.h 25 * @brief Packetizes H.263 bitstream into RTP payload.25 * @brief Packetizes/unpacketizes H.263 bitstream into RTP payload. 26 26 */ 27 27 28 #include <pj/errno.h> 28 #include <pj/pool.h> 29 #include <pj/types.h> 29 30 30 31 PJ_BEGIN_DECL 31 32 32 /**33 * Find synchronization point (PSC, slice, GSBC, EOS, EOSBS) in H.26334 * 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 }49 33 50 34 /** 51 * Generate an RTP payload from H.263 frame bitstream, in-place processing.35 * Opaque declaration for H.263 packetizer. 52 36 */ 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; 37 typedef struct pjmedia_h263_packetizer pjmedia_h263_packetizer; 61 38 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 override68 * 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 octets73 * 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/MTU87 * 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 }99 39 100 40 /** 101 * Append RTP payload to a H.263 picture bitstream.41 * Enumeration of H.263 packetization modes. 102 42 */ 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) 43 typedef enum 107 44 { 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, 111 49 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, 115 55 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; 122 57 123 /* Get bitstream length */124 payload_len -= (p-payload);125 58 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 */ 62 typedef struct pjmedia_h263_packetizer_cfg 63 { 64 /** 65 * Maximum payload length. 66 * Default: PJMEDIA_MAX_MTU 67 */ 68 int mtu; 128 69 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; 134 75 135 /* Add the bitstream */ 136 pj_memcpy(bits, p, payload_len); 76 } pjmedia_h263_packetizer_cfg; 137 77 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 */ 89 PJ_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 */ 109 PJ_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 */ 135 PJ_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); 140 141 141 142 -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/format.h
r3461 r3493 458 458 { 459 459 #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)); 462 462 #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)); 464 464 #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)); 466 466 #endif 467 467 } -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/vid_codec.h
r3461 r3493 224 224 * belong to the same picture will share the same RTP timestamp and also 225 225 * 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. 227 229 * 228 230 * @param codec The codec instance … … 242 244 pj_size_t payload_len, 243 245 pj_uint8_t *bits, 244 pj_size_t *bits_len); 246 pj_size_t bits_len, 247 unsigned *bits_pos); 245 248 246 249 /** -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
r3469 r3493 19 19 #include <pjmedia-codec/ffmpeg_codecs.h> 20 20 #include <pjmedia-codec/h263_packetizer.h> 21 #include <pjmedia-codec/h264_packetizer.h> 21 22 #include <pjmedia/errno.h> 23 #include <pjmedia/vid_codec_util.h> 22 24 #include <pj/assert.h> 23 25 #include <pj/list.h> … … 39 41 #include <libavcodec/avcodec.h> 40 42 #include <libavformat/avformat.h> 41 #include <libswscale/swscale.h>42 43 44 #define PJMEDIA_FORMAT_FFMPEG_UNKNOWN PJMEDIA_FORMAT_PACK('f','f','0','0');45 43 46 44 … … 80 78 pj_size_t payload_len, 81 79 pj_uint8_t *buf, 82 pj_size_t *buf_len); 80 pj_size_t buf_len, 81 unsigned *pos); 83 82 static pj_status_t ffmpeg_codec_encode( pjmedia_vid_codec *codec, 84 83 const pjmedia_frame *input, … … 131 130 typedef struct ffmpeg_codec_desc ffmpeg_codec_desc; 132 131 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 };157 132 158 133 /* FFMPEG codecs private data. */ 159 typedef struct ffmpeg_private { 134 typedef struct ffmpeg_private 135 { 160 136 const ffmpeg_codec_desc *desc; 161 137 pjmedia_vid_codec_param param; /**< Codec param */ … … 180 156 */ 181 157 enum PixelFormat expected_dec_fmt; 182 /**< expected output format of158 /**< Expected output format of 183 159 ffmpeg decoder */ 160 161 void *data; /**< Codec specific data */ 184 162 } ffmpeg_private; 185 163 186 164 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 178 typedef FUNC_PACKETIZE(*func_packetize); 179 typedef FUNC_UNPACKETIZE(*func_unpacketize); 180 typedef pj_status_t (*func_preopen) (ffmpeg_private *ff); 181 typedef pj_status_t (*func_postopen) (ffmpeg_private *ff); 182 200 183 201 184 /* FFMPEG codec info */ 202 struct ffmpeg_codec_desc { 185 struct ffmpeg_codec_desc 186 { 203 187 /* Predefined info */ 204 188 pjmedia_vid_codec_info info; … … 208 192 func_packetize packetize; 209 193 func_unpacketize unpacketize; 210 func_parse_fmtp parse_fmtp; 194 func_preopen preopen; 195 func_preopen postopen; 211 196 pjmedia_codec_fmtp dec_fmtp; 212 197 … … 217 202 }; 218 203 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 */ 206 static pj_status_t h264_preopen(ffmpeg_private *ff); 207 static pj_status_t h264_postopen(ffmpeg_private *ff); 208 static pj_status_t h263_preopen(ffmpeg_private *ff); 209 static FUNC_PACKETIZE(h264_packetize); 210 static FUNC_UNPACKETIZE(h264_unpacketize); 211 static FUNC_PACKETIZE(h263_packetize); 212 static FUNC_UNPACKETIZE(h263_unpacketize); 242 213 243 214 … … 245 216 ffmpeg_codec_desc codec_desc[] = 246 217 { 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 }, 247 226 { 248 227 {PJMEDIA_FORMAT_H263P, {"H263-1998",9}, PJMEDIA_RTP_PT_H263P}, 249 228 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}}, } }, 252 232 }, 253 233 { 254 234 {PJMEDIA_FORMAT_H263, {"H263",4}, PJMEDIA_RTP_PT_H263}, 255 },256 {257 {PJMEDIA_FORMAT_H264, {"H264",4}, PJMEDIA_RTP_PT_H264},258 235 }, 259 236 { … … 272 249 }; 273 250 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 252 typedef struct h264_data 253 { 254 pjmedia_vid_codec_h264_fmtp fmtp; 255 pjmedia_h264_packetizer *pktz; 256 } h264_data; 257 258 259 static 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 292 288 } 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 305 static 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 318 static 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 325 static 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 333 typedef struct h263_data 334 { 335 pjmedia_h263_packetizer *pktz; 336 } h263_data; 337 338 /* H263 pre-open */ 339 static pj_status_t h263_preopen(ffmpeg_private *ff) 340 { 341 h263_data *data; 342 pjmedia_h263_packetizer_cfg pktz_cfg; 380 343 pj_status_t status; 381 344 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, ¶m_ref); 400 fmtp_ref = (status==PJ_SUCCESS)? ¶m_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 361 static 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 368 static 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 } 462 374 463 375 … … 810 722 attr->enc_fmt.det.vid.max_bps = desc->max_bps; 811 723 724 /* MTU */ 725 attr->enc_mtu = PJMEDIA_MAX_MTU; 726 812 727 return PJ_SUCCESS; 813 728 } … … 934 849 935 850 static enum PixelFormat dec_get_format(struct AVCodecContext *s, 936 851 const enum PixelFormat * fmt) 937 852 { 938 853 ffmpeg_private *ff = (ffmpeg_private*)s->opaque; … … 954 869 { 955 870 enum PixelFormat pix_fmt; 871 pjmedia_video_format_detail *vfd; 872 pj_bool_t enc_opened = PJ_FALSE, dec_opened = PJ_FALSE; 956 873 pj_status_t status; 957 pjmedia_video_format_detail *vfd; 958 874 875 /* Get decoded pixel format */ 959 876 status = pjmedia_format_id_to_PixelFormat(ff->param.dec_fmt.id, 960 877 &pix_fmt); 961 878 if (status != PJ_SUCCESS) 962 879 return status; 963 880 ff->expected_dec_fmt = pix_fmt; 881 882 /* Get video format detail for shortcut access to encoded format */ 964 883 vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, 965 884 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; 974 907 int err; 975 908 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 */ 987 910 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; 988 921 ctx->workaround_bugs = FF_BUG_AUTODETECT; 989 922 ctx->opaque = ff; 990 923 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 */ 1038 925 pj_mutex_lock(ff_mutex); 1039 err = avcodec_open(ctx, codec);926 err = avcodec_open(ctx, ff->enc); 1040 927 pj_mutex_unlock(ff_mutex); 1041 928 if (err < 0) { 1042 929 print_ffmpeg_err(err); 1043 return PJMEDIA_CODEC_EFAILED; 930 status = PJMEDIA_CODEC_EFAILED; 931 goto on_error; 1044 932 } 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 970 on_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; 1053 984 } 1054 985 … … 1067 998 1068 999 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 }1076 1000 1077 1001 /* Open the codec */ … … 1179 1103 1180 1104 static pj_status_t ffmpeg_packetize ( pjmedia_vid_codec *codec, 1181 pj_uint8_t *b uf,1182 pj_size_t b uf_len,1183 unsigned * pos,1105 pj_uint8_t *bits, 1106 pj_size_t bits_len, 1107 unsigned *bits_pos, 1184 1108 const pj_uint8_t **payload, 1185 1109 pj_size_t *payload_len) … … 1188 1112 1189 1113 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); 1193 1116 } 1194 1117 … … 1199 1122 const pj_uint8_t *payload, 1200 1123 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) 1203 1127 { 1204 1128 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 1205 1129 1206 1130 if (ff->desc->unpacketize) { 1207 return (*ff->desc->unpacketize)( payload, payload_len,1208 b uf, buf_len);1131 return (*ff->desc->unpacketize)(ff, payload, payload_len, 1132 bits, bits_len, bits_pos); 1209 1133 } 1210 1134 … … 1227 1151 int out_buf_len = output_buf_len; 1228 1152 int err; 1229 1153 AVRational src_timebase; 1230 1154 /* For some reasons (e.g: SSE/MMX usage), the avcodec_encode_video() must 1231 1155 * have stack aligned to 16 bytes. Let's try to be safe by preparing the … … 1234 1158 PJ_ALIGN_DATA(pj_uint32_t i[4], 16); 1235 1159 1160 if ((long)i & 0xF) { 1161 PJ_LOG(2,(THIS_FILE, "Stack alignment fails")); 1162 } 1163 1236 1164 /* Check if encoder has been opened */ 1237 1165 PJ_ASSERT_RETURN(ff->enc_ctx, PJ_EINVALIDOP); 1238 1166 1239 1167 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); 1241 1172 1242 1173 for (i[0] = 0; i[0] < ff->enc_vfi->plane_cnt; ++i[0]) { … … 1304 1235 1305 1236 #if LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72 1306 avpacket.flags = AV_PKT_FLAG_KEY;1237 //avpacket.flags = AV_PKT_FLAG_KEY; 1307 1238 #else 1308 1239 avpacket.flags = 0; -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/sdp_neg.c
r3347 r3493 53 53 }; 54 54 55 #define GET_FMTP_IVAL (ival, fmtp, param, default_val) \55 #define GET_FMTP_IVAL_BASE(ival, base, fmtp, param, default_val) \ 56 56 do { \ 57 57 pj_str_t s; \ … … 64 64 pj_strset(&s, p + param.slen, fmtp.fmt_param.slen - \ 65 65 (p - fmtp.fmt_param.ptr) - param.slen); \ 66 ival = pj_strtoul (&s); \66 ival = pj_strtoul2(&s, NULL, base); \ 67 67 } 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 68 72 69 73 /* … … 679 683 680 684 685 /* Matching H.264 between offer and answer. */ 686 static 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 681 728 /* Toggle AMR octet-align setting in the fmtp. 682 729 */ … … 877 924 { 878 925 /* 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 { 880 928 if (match_g7221(offer, i, answer, j)) 881 929 break; … … 887 935 if (match_amr(offer, i, answer, j, PJ_FALSE, 888 936 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)) 889 943 break; 890 944 } else { … … 1200 1254 PJ_TRUE, &pt_amr_need_adapt)) 1201 1255 continue; 1256 } else 1257 if (pj_stricmp2(&or_.enc_name, "H264") == 0 && 1258 !match_h264(master, i, slave, j)) 1259 { 1260 continue; 1202 1261 } 1203 1262 found_matching_codec = 1; -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_stream.c
r3461 r3493 769 769 LOGERR_((channel->port.info.name.ptr, 770 770 "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); 771 775 return status; 772 776 } … … 789 793 LOGERR_((channel->port.info.name.ptr, 790 794 "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); 791 799 return status; 792 800 } … … 867 875 */ 868 876 { 869 pj_uint8_t *p, *data;870 char ptype;871 pj_size_t psize, data_len;872 pj_uint32_t ts;873 int seq;874 877 pj_bool_t got_frame; 875 unsigned i;878 unsigned cnt; 876 879 877 880 channel->buf_len = 0; … … 881 884 pj_mutex_lock( stream->jb_mutex ); 882 885 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); 887 895 if (ptype == PJMEDIA_JB_NORMAL_FRAME) { 888 896 if (last_ts == 0) { … … 890 898 frm_first_seq = seq; 891 899 } 892 893 900 if (ts != last_ts) { 894 901 got_frame = PJ_TRUE; 895 pjmedia_jbuf_remove_frame(stream->jb, i);896 902 break; 897 903 } 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;905 904 frm_last_seq = seq; 906 905 } else if (ptype == PJMEDIA_JB_ZERO_EMPTY_FRAME) { … … 908 907 break; 909 908 } 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); 910 947 } 911 948 -
pjproject/branches/projects/2.0-dev/pjmedia/src/test/vid_codec_test.c
r3425 r3493 7 7 #define THIS_FILE "vid_codec.c" 8 8 9 #define BYPASS_CODEC 0 9 #define BYPASS_CODEC 0 10 #define BYPASS_PACKETIZER 0 10 11 11 12 typedef struct codec_port_data_t … … 15 16 pj_uint8_t *enc_buf; 16 17 pj_size_t enc_buf_size; 18 pj_uint8_t *pack_buf; 19 pj_size_t pack_buf_size; 17 20 } codec_port_data_t; 18 21 … … 33 36 status = codec->op->encode(codec, frame, enc_frame.size, &enc_frame); 34 37 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 35 78 status = codec->op->decode(codec, &enc_frame, frame->size, frame); 36 79 if (status != PJ_SUCCESS) goto on_error; … … 78 121 79 122 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", 81 124 info[i].encoding_name.slen, info[i].encoding_name.ptr, 82 125 (info[i].dir & PJMEDIA_DIR_ENCODING? 'E' : ' '), … … 123 166 } 124 167 168 125 169 /* Lookup colorbar source */ 126 170 status = pjmedia_vid_dev_lookup("Colorbar", "Colorbar generator", &cap_idx); … … 135 179 } 136 180 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. 137 186 /* Raw format ID "not specified", lets find common format among the codec 138 187 * and the video devices … … 166 215 } 167 216 } 217 #endif 168 218 169 219 /* Prepare codec */ … … 265 315 codec_port_data.enc_buf = pj_pool_alloc(pool, 266 316 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); 267 320 268 321 codec_port.put_frame = &codec_put_frame;
Note: See TracChangeset
for help on using the changeset viewer.