Changeset 3420
- Timestamp:
- Feb 24, 2011 7:47:55 AM (14 years ago)
- Location:
- pjproject/branches/projects/2.0-dev/pjmedia
- Files:
-
- 2 added
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/build/pjmedia.vcproj
r3394 r3420 4313 4313 </File> 4314 4314 <File 4315 RelativePath="..\src\pjmedia\s ession.c"4315 RelativePath="..\src\pjmedia\silencedet.c" 4316 4316 > 4317 4317 <FileConfiguration … … 4371 4371 </File> 4372 4372 <File 4373 RelativePath="..\src\pjmedia\silencedet.c" 4373 RelativePath="..\src\pjmedia\sound_legacy.c" 4374 > 4375 </File> 4376 <File 4377 RelativePath="..\src\pjmedia\sound_port.c" 4374 4378 > 4375 4379 <FileConfiguration … … 4429 4433 </File> 4430 4434 <File 4431 RelativePath="..\src\pjmedia\sound_legacy.c" 4432 > 4433 </File> 4434 <File 4435 RelativePath="..\src\pjmedia\sound_port.c" 4435 RelativePath="..\src\pjmedia\splitcomb.c" 4436 4436 > 4437 4437 <FileConfiguration … … 4491 4491 </File> 4492 4492 <File 4493 RelativePath="..\src\pjmedia\splitcomb.c" 4493 RelativePath="..\src\pjmedia\stereo_port.c" 4494 > 4495 </File> 4496 <File 4497 RelativePath="..\src\pjmedia\stream.c" 4494 4498 > 4495 4499 <FileConfiguration … … 4549 4553 </File> 4550 4554 <File 4551 RelativePath="..\src\pjmedia\st ereo_port.c"4552 > 4553 </File> 4554 <File 4555 RelativePath="..\src\pjmedia\ stream.c"4555 RelativePath="..\src\pjmedia\stream_common.c" 4556 > 4557 </File> 4558 <File 4559 RelativePath="..\src\pjmedia\tonegen.c" 4556 4560 > 4557 4561 <FileConfiguration … … 4611 4615 </File> 4612 4616 <File 4613 RelativePath="..\src\pjmedia\tonegen.c" 4617 RelativePath="..\src\pjmedia\transport_adapter_sample.c" 4618 > 4619 </File> 4620 <File 4621 RelativePath="..\src\pjmedia\transport_ice.c" 4622 > 4623 </File> 4624 <File 4625 RelativePath="..\src\pjmedia\transport_loop.c" 4626 > 4627 </File> 4628 <File 4629 RelativePath="..\src\pjmedia\transport_srtp.c" 4630 > 4631 </File> 4632 <File 4633 RelativePath="..\src\pjmedia\transport_udp.c" 4614 4634 > 4615 4635 <FileConfiguration … … 4669 4689 </File> 4670 4690 <File 4671 RelativePath="..\src\pjmedia\transport_adapter_sample.c"4672 >4673 </File>4674 <File4675 RelativePath="..\src\pjmedia\transport_ice.c"4676 >4677 </File>4678 <File4679 RelativePath="..\src\pjmedia\transport_loop.c"4680 >4681 </File>4682 <File4683 RelativePath="..\src\pjmedia\transport_srtp.c"4684 >4685 </File>4686 <File4687 RelativePath="..\src\pjmedia\transport_udp.c"4688 >4689 <FileConfiguration4690 Name="Release|Win32"4691 >4692 <Tool4693 Name="VCCLCompilerTool"4694 AdditionalIncludeDirectories=""4695 PreprocessorDefinitions=""4696 />4697 </FileConfiguration>4698 <FileConfiguration4699 Name="Debug|Win32"4700 >4701 <Tool4702 Name="VCCLCompilerTool"4703 AdditionalIncludeDirectories=""4704 PreprocessorDefinitions=""4705 />4706 </FileConfiguration>4707 <FileConfiguration4708 Name="Debug-Static|Win32"4709 >4710 <Tool4711 Name="VCCLCompilerTool"4712 AdditionalIncludeDirectories=""4713 PreprocessorDefinitions=""4714 />4715 </FileConfiguration>4716 <FileConfiguration4717 Name="Release-Dynamic|Win32"4718 >4719 <Tool4720 Name="VCCLCompilerTool"4721 AdditionalIncludeDirectories=""4722 PreprocessorDefinitions=""4723 />4724 </FileConfiguration>4725 <FileConfiguration4726 Name="Debug-Dynamic|Win32"4727 >4728 <Tool4729 Name="VCCLCompilerTool"4730 AdditionalIncludeDirectories=""4731 PreprocessorDefinitions=""4732 />4733 </FileConfiguration>4734 <FileConfiguration4735 Name="Release-Static|Win32"4736 >4737 <Tool4738 Name="VCCLCompilerTool"4739 AdditionalIncludeDirectories=""4740 PreprocessorDefinitions=""4741 />4742 </FileConfiguration>4743 </File>4744 <File4745 4691 RelativePath="..\src\pjmedia\vid_codec.c" 4692 > 4693 </File> 4694 <File 4695 RelativePath="..\src\pjmedia\vid_stream.c" 4746 4696 > 4747 4697 </File> … … 5120 5070 </File> 5121 5071 <File 5122 RelativePath="..\include\pjmedia\session.h"5123 >5124 </File>5125 <File5126 5072 RelativePath="..\include\pjmedia\silencedet.h" 5127 5073 > … … 5148 5094 </File> 5149 5095 <File 5096 RelativePath="..\include\pjmedia\stream_common.h" 5097 > 5098 </File> 5099 <File 5150 5100 RelativePath="..\include\pjmedia\tonegen.h" 5151 5101 > … … 5181 5131 <File 5182 5132 RelativePath="..\include\pjmedia\vid_codec.h" 5133 > 5134 </File> 5135 <File 5136 RelativePath="..\include\pjmedia\vid_stream.h" 5183 5137 > 5184 5138 </File> -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev.h
r3401 r3420 79 79 * 80 80 * Once video stream is running, application can also retrieve or set some 81 * specific video capability, by using #pjmedia_vid_ stream_get_cap() and82 * #pjmedia_vid_ stream_set_cap() and specifying the desired capability. The81 * specific video capability, by using #pjmedia_vid_dev_stream_get_cap() and 82 * #pjmedia_vid_dev_stream_set_cap() and specifying the desired capability. The 83 83 * value of the capability is specified as pointer, and application needs to 84 84 * supply the pointer with the correct value, according to the documentation … … 155 155 156 156 157 /** Forward declaration for pjmedia_vid_ stream */158 typedef struct pjmedia_vid_ stream pjmedia_vid_stream;157 /** Forward declaration for pjmedia_vid_dev_stream */ 158 typedef struct pjmedia_vid_dev_stream pjmedia_vid_dev_stream; 159 159 160 160 typedef enum pjmedia_event_type … … 188 188 * stream to stop 189 189 */ 190 pj_status_t (*capture_cb)(pjmedia_vid_ stream *stream,190 pj_status_t (*capture_cb)(pjmedia_vid_dev_stream *stream, 191 191 void *user_data, 192 192 pjmedia_frame *frame); … … 211 211 * stream to stop 212 212 */ 213 pj_status_t (*render_cb)(pjmedia_vid_ stream *stream,213 pj_status_t (*render_cb)(pjmedia_vid_dev_stream *stream, 214 214 void *user_data, 215 215 pjmedia_frame *frame); … … 227 227 * video stream will ignore the particular event. 228 228 */ 229 pj_status_t (*on_event_cb)(pjmedia_vid_ stream *stream,229 pj_status_t (*on_event_cb)(pjmedia_vid_dev_stream *stream, 230 230 void *user_data, 231 231 pjmedia_vid_event *event); … … 477 477 * error code. 478 478 */ 479 PJ_DECL(pj_status_t) pjmedia_vid_stream_create(const pjmedia_vid_param *param, 480 const pjmedia_vid_cb *cb, 481 void *user_data, 482 pjmedia_vid_stream **p_strm); 479 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_create( 480 const pjmedia_vid_param *param, 481 const pjmedia_vid_cb *cb, 482 void *user_data, 483 pjmedia_vid_dev_stream **p_strm); 483 484 484 485 /** … … 492 493 * error code. 493 494 */ 494 PJ_DECL(pj_status_t) pjmedia_vid_stream_get_param(pjmedia_vid_stream *strm, 495 pjmedia_vid_param *param); 495 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_param( 496 pjmedia_vid_dev_stream *strm, 497 pjmedia_vid_param *param); 496 498 497 499 /** … … 508 510 * error code. 509 511 */ 510 PJ_DECL(pj_status_t) pjmedia_vid_stream_get_cap(pjmedia_vid_stream *strm, 511 pjmedia_vid_dev_cap cap, 512 void *value); 512 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_cap( 513 pjmedia_vid_dev_stream *strm, 514 pjmedia_vid_dev_cap cap, 515 void *value); 513 516 514 517 /** … … 523 526 * error code. 524 527 */ 525 PJ_DECL(pj_status_t) pjmedia_vid_stream_set_cap(pjmedia_vid_stream *strm, 526 pjmedia_vid_dev_cap cap, 527 const void *value); 528 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_set_cap( 529 pjmedia_vid_dev_stream *strm, 530 pjmedia_vid_dev_cap cap, 531 const void *value); 528 532 529 533 /** … … 535 539 * error code. 536 540 */ 537 PJ_DECL(pj_status_t) pjmedia_vid_stream_start(pjmedia_vid_stream *strm); 541 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_start( 542 pjmedia_vid_dev_stream *strm); 538 543 539 544 /* Get/put frame API for passive stream */ 540 PJ_DECL(pj_status_t) pjmedia_vid_stream_get_frame(pjmedia_vid_stream *strm, 541 pjmedia_frame *frame); 542 543 PJ_DECL(pj_status_t) pjmedia_vid_stream_put_frame(pjmedia_vid_stream *strm, 544 const pjmedia_frame *frame); 545 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame( 546 pjmedia_vid_dev_stream *strm, 547 pjmedia_frame *frame); 548 549 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_put_frame( 550 pjmedia_vid_dev_stream *strm, 551 const pjmedia_frame *frame); 545 552 546 553 /** … … 552 559 * error code. 553 560 */ 554 PJ_DECL(pj_status_t) pjmedia_vid_stream_stop(pjmedia_vid_stream *strm); 561 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_stop( 562 pjmedia_vid_dev_stream *strm); 555 563 556 564 /** … … 562 570 * error code. 563 571 */ 564 PJ_DECL(pj_status_t) pjmedia_vid_stream_destroy(pjmedia_vid_stream *strm); 572 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_destroy( 573 pjmedia_vid_dev_stream *strm); 565 574 566 575 -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev_imp.h
r3392 r3420 84 84 /** 85 85 * Open the video device and create video stream. See 86 * #pjmedia_vid_ stream_create()86 * #pjmedia_vid_dev_stream_create() 87 87 */ 88 88 pj_status_t (*create_stream)(pjmedia_vid_dev_factory *f, … … 90 90 const pjmedia_vid_cb *cb, 91 91 void *user_data, 92 pjmedia_vid_ stream **p_vid_strm);92 pjmedia_vid_dev_stream **p_vid_strm); 93 93 94 94 } pjmedia_vid_dev_factory_op; … … 114 114 * Video stream operations. 115 115 */ 116 typedef struct pjmedia_vid_ stream_op116 typedef struct pjmedia_vid_dev_stream_op 117 117 { 118 118 /** 119 * See #pjmedia_vid_ stream_get_param()119 * See #pjmedia_vid_dev_stream_get_param() 120 120 */ 121 pj_status_t (*get_param)(pjmedia_vid_ stream *strm,121 pj_status_t (*get_param)(pjmedia_vid_dev_stream *strm, 122 122 pjmedia_vid_param *param); 123 123 124 124 /** 125 * See #pjmedia_vid_ stream_get_cap()125 * See #pjmedia_vid_dev_stream_get_cap() 126 126 */ 127 pj_status_t (*get_cap)(pjmedia_vid_ stream *strm,127 pj_status_t (*get_cap)(pjmedia_vid_dev_stream *strm, 128 128 pjmedia_vid_dev_cap cap, 129 129 void *value); 130 130 131 131 /** 132 * See #pjmedia_vid_ stream_set_cap()132 * See #pjmedia_vid_dev_stream_set_cap() 133 133 */ 134 pj_status_t (*set_cap)(pjmedia_vid_ stream *strm,134 pj_status_t (*set_cap)(pjmedia_vid_dev_stream *strm, 135 135 pjmedia_vid_dev_cap cap, 136 136 const void *value); 137 137 138 138 /** 139 * See #pjmedia_vid_ stream_start()139 * See #pjmedia_vid_dev_stream_start() 140 140 */ 141 pj_status_t (*start)(pjmedia_vid_ stream *strm);141 pj_status_t (*start)(pjmedia_vid_dev_stream *strm); 142 142 143 143 /** 144 * See #pjmedia_vid_ stream_get_frame()144 * See #pjmedia_vid_dev_stream_get_frame() 145 145 */ 146 pj_status_t (*get_frame)(pjmedia_vid_ stream *strm,146 pj_status_t (*get_frame)(pjmedia_vid_dev_stream *strm, 147 147 pjmedia_frame *frame); 148 148 149 149 /** 150 * See #pjmedia_vid_ stream_put_frame()150 * See #pjmedia_vid_dev_stream_put_frame() 151 151 */ 152 pj_status_t (*put_frame)(pjmedia_vid_ stream *strm,152 pj_status_t (*put_frame)(pjmedia_vid_dev_stream *strm, 153 153 const pjmedia_frame *frame); 154 154 155 155 /** 156 * See #pjmedia_vid_ stream_stop().156 * See #pjmedia_vid_dev_stream_stop(). 157 157 */ 158 pj_status_t (*stop)(pjmedia_vid_ stream *strm);158 pj_status_t (*stop)(pjmedia_vid_dev_stream *strm); 159 159 160 160 /** 161 * See #pjmedia_vid_ stream_destroy().161 * See #pjmedia_vid_dev_stream_destroy(). 162 162 */ 163 pj_status_t (*destroy)(pjmedia_vid_ stream *strm);163 pj_status_t (*destroy)(pjmedia_vid_dev_stream *strm); 164 164 165 } pjmedia_vid_ stream_op;165 } pjmedia_vid_dev_stream_op; 166 166 167 167 … … 169 169 * This structure describes the video device stream. 170 170 */ 171 struct pjmedia_vid_ stream171 struct pjmedia_vid_dev_stream 172 172 { 173 173 /** Internal data to be initialized by video subsystem */ … … 178 178 179 179 /** Operations */ 180 pjmedia_vid_ stream_op *op;180 pjmedia_vid_dev_stream_op *op; 181 181 }; 182 182 -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia.h
r3392 r3420 53 53 #include <pjmedia/sdp.h> 54 54 #include <pjmedia/sdp_neg.h> 55 #include <pjmedia/session.h>55 //#include <pjmedia/session.h> 56 56 #include <pjmedia/silencedet.h> 57 57 #include <pjmedia/sound.h> … … 60 60 #include <pjmedia/stereo.h> 61 61 #include <pjmedia/stream.h> 62 #include <pjmedia/stream_common.h> 62 63 #include <pjmedia/tonegen.h> 63 64 #include <pjmedia/transport.h> … … 69 70 #include <pjmedia/videoport.h> 70 71 #include <pjmedia/vid_codec.h> 72 #include <pjmedia/vid_stream.h> 71 73 #include <pjmedia/wav_playlist.h> 72 74 #include <pjmedia/wav_port.h> -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/config.h
r3402 r3420 980 980 981 981 /** 982 * Maximum video frame size. 983 * Default: 16kB 984 */ 985 #ifndef PJMEDIA_MAX_VIDEO_FRAME_SIZE 986 # define PJMEDIA_MAX_VIDEO_FRAME_SIZE (1<<14) 987 #endif 988 989 990 /** 982 991 * Specify the maximum duration (in ms) for resynchronization. When a media 983 992 * is late to another media it is supposed to be synchronized to, it is -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/jbuf.h
r3065 r3420 69 69 * This structure describes jitter buffer state. 70 70 */ 71 struct pjmedia_jb_state71 typedef struct pjmedia_jb_state 72 72 { 73 73 /* Setting */ … … 90 90 unsigned discard; /**< Number of discarded frames. */ 91 91 unsigned empty; /**< Number of empty on GET events. */ 92 }; 93 94 95 /** 96 * @see pjmedia_jb_state 97 */ 98 typedef struct pjmedia_jb_state pjmedia_jb_state; 92 } pjmedia_jb_state; 99 93 100 94 … … 181 175 182 176 /** 177 * Enable/disable the jitter buffer drift detection and handling mechanism. 178 * The default behavior is enabled. 179 * 180 * @param jb The jitter buffer 181 * @param enable Set to PJ_TRUE to enable or PJ_FALSE to disable. 182 * 183 * @return PJ_SUCCESS on success. 184 */ 185 PJ_DECL(pj_status_t) pjmedia_jbuf_enable_discard(pjmedia_jbuf *jb, 186 pj_bool_t enable); 187 188 189 /** 183 190 * Destroy jitter buffer instance. 184 191 * … … 244 251 pj_bool_t *discarded); 245 252 253 /** 254 * Put a frame to the jitter buffer. If the frame can be accepted (based 255 * on the sequence number), the jitter buffer will copy the frame and put 256 * it in the appropriate position in the buffer. 257 * 258 * Application MUST manage it's own synchronization when multiple threads 259 * are accessing the jitter buffer at the same time. 260 * 261 * @param jb The jitter buffer. 262 * @param frame Pointer to frame buffer to be stored in the jitter 263 * buffer. 264 * @param size The frame size. 265 * @param bit_info Bit precise info of the frame, e.g: a frame may not 266 * exactly start and end at the octet boundary, so this 267 * field may be used for specifying start & end bit offset. 268 * @param frame_seq The frame sequence number. 269 * @param frame_ts The frame timestamp. 270 * @param discarded Flag whether the frame is discarded by jitter buffer. 271 */ 272 PJ_DECL(void) pjmedia_jbuf_put_frame3( pjmedia_jbuf *jb, 273 const void *frame, 274 pj_size_t size, 275 pj_uint32_t bit_info, 276 int frame_seq, 277 pj_uint32_t frame_ts, 278 pj_bool_t *discarded); 246 279 /** 247 280 * Get a frame from the jitter buffer. The jitter buffer will return the … … 294 327 295 328 329 PJ_DECL(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb, 330 void *frame, 331 pj_size_t *size, 332 char *p_frm_type, 333 pj_uint32_t *bit_info, 334 pj_uint32_t *ts); 335 336 PJ_DECL(void) pjmedia_jbuf_peek_frame(pjmedia_jbuf *jb, 337 unsigned idx, 338 const void **frame, 339 pj_size_t *size, 340 char *p_frm_type, 341 pj_uint32_t *bit_info, 342 pj_uint32_t *ts); 343 344 PJ_DECL(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb, 345 unsigned frame_cnt); 346 347 296 348 /** 297 349 * Get jitter buffer current state/settings. -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/stream.h
r3418 r3420 144 144 145 145 146 /** 147 * This function will initialize the stream info based on information 148 * in both SDP session descriptors for the specified stream index. 149 * The remaining information will be taken from default codec parameters. 150 * If socket info array is specified, the socket will be copied to the 151 * session info as well. 152 * 153 * @param si Stream info structure to be initialized. 154 * @param pool Pool to allocate memory. 155 * @param endpt PJMEDIA endpoint instance. 156 * @param local Local SDP session descriptor. 157 * @param remote Remote SDP session descriptor. 158 * @param stream_idx Media stream index in the session descriptor. 159 * 160 * @return PJ_SUCCESS if stream info is successfully initialized. 161 */ 162 PJ_DECL(pj_status_t) 163 pjmedia_stream_info_from_sdp( pjmedia_stream_info *si, 164 pj_pool_t *pool, 165 pjmedia_endpt *endpt, 166 const pjmedia_sdp_session *local, 167 const pjmedia_sdp_session *remote, 168 unsigned stream_idx); 169 146 170 147 171 /** -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/vid_codec.h
r3392 r3420 23 23 24 24 /** 25 * @file codec.h26 * @brief Codec framework.25 * @file vid_codec.h 26 * @brief Video codec framework. 27 27 */ 28 28 … … 46 46 pjmedia_format_id fmt_id; /**< Encoded format ID */ 47 47 pj_str_t encoding_name; /**< Encoding name */ 48 unsigned pt; /**< Payload type (may be 255 for 49 dynamic payload type) */ 50 unsigned clock_rate; /**< Clock rate */ 48 51 pjmedia_dir dir; /**< Direction */ 49 unsigned pt; /**< Payload type (may be 0 for 50 dynamic payload type) */ 51 unsigned clock_rate; /**< (?) Clock rate */ 52 unsigned dec_fmt_id_cnt; 52 unsigned dec_fmt_id_cnt; /**< # of supported encoding source 53 format IDs */ 53 54 pjmedia_format_id dec_fmt_id[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT]; 54 55 /**< Supported encoding source 55 56 format IDs */ 56 unsigned fps_cnt; /**< zero if support any fps */57 pjmedia_ratio fps[PJMEDIA_VID_CODEC_MAX_FPS_CNT]; 58 /**< (?) supported FPSes,59 ffmpeg has this*/57 unsigned fps_cnt; /**< # of supported frame-rates, can be 58 zero (support any frame-rate) */ 59 pjmedia_ratio fps[PJMEDIA_VID_CODEC_MAX_FPS_CNT]; 60 /**< Supported frame-rates */ 60 61 } pjmedia_vid_codec_info; 62 61 63 62 64 /** … … 80 82 81 83 unsigned enc_mtu; /**< MTU or max payload size setting*/ 82 unsigned pt; /**< Payload type. */83 84 } pjmedia_vid_codec_param; 84 85 85 86 86 87 /* 88 * Forward declaration for pjmedia_vid_codec. 87 /** 88 * Enumeration of video codec events. 89 */ 90 typedef enum pjmedia_vid_codec_event 91 { 92 /** 93 * Format changed event. The decoder output format is not really 94 * configurable, so that the output format setting configured in the 95 * initialization may be changed. Application can catch this event 96 * by checking the bit_info field of the pjmedia_frame of the decoder 97 * output frame. 98 */ 99 PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED = 1, 100 101 } pjmedia_vid_codec_event; 102 103 104 /** 105 * Forward declaration for video codec. 89 106 */ 90 107 typedef struct pjmedia_vid_codec pjmedia_vid_codec; … … 112 129 * Open the codec and initialize with the specified parameter. 113 130 * Upon successful initialization, the codec may modify the parameter 114 * and fills in the unspecified values (such as enc_ptime, when 115 * encoder ptime is different than decoder ptime). 131 * and fills in the unspecified values (such as size or frame rate of 132 * the encoder format, as it may need to be negotiated with remote 133 * preferences via SDP fmtp). 116 134 * 117 135 * @param codec The codec instance. … … 139 157 * non-PJ_SUCCESS, and the original parameters will not be changed. 140 158 * 141 * Application can expect changing trivial codec settings such as142 * changing VAD setting to succeed.143 *144 159 * @param codec The codec instance. 145 160 * @param param The new codec parameter. … … 148 163 */ 149 164 pj_status_t (*modify)(pjmedia_vid_codec *codec, 150 const pjmedia_vid_codec_param *param ); 165 const pjmedia_vid_codec_param *param); 166 167 /** 168 * Get the codec parameter after the codec is opened. 169 * 170 * @param codec The codec instance. 171 * @param param The codec parameter. 172 * 173 * @return PJ_SUCCESS on success. 174 */ 175 pj_status_t (*get_param)(pjmedia_vid_codec *codec, 176 pjmedia_vid_codec_param *param); 151 177 152 178 /** 153 * Instruct the codec to inspect the specified payload/packet and 154 * split the packet into individual base frames. Each output frames will 155 * have ptime that is equal to basic frame ptime (i.e. the value of 156 * info.frm_ptime in #pjmedia_vid_codec_param). 179 * Instruct the codec to generate a payload/packet from a picture 180 * bitstream to be sent (via network). The maximum payload size or 181 * MTU is configurable via enc_mtu field of #pjmedia_vid_codec_param. 182 * For a long bitstream, application usually need to call this function 183 * multiple times until the whole bitstream is sent. Note that, for 184 * performance reason, the packetization will be done in-place, so the 185 * original bitstream may be modified by this function. 186 * 187 * @param codec The codec instance 188 * @param bits The picture bitstream. 189 * @param bits_len The length of the bitstream. 190 * @param bits_pos On input, the start position of the bitstream 191 * to be packetized. On output, the next position for 192 * next packet. 193 * @param pkt The pointer of the generated payload. 194 * @param pkt_len The payload length. 195 * 196 * @return PJ_SUCCESS on success. 197 */ 198 pj_status_t (*packetize) (pjmedia_vid_codec *codec, 199 pj_uint8_t *bits, 200 pj_size_t bits_len, 201 unsigned *bits_pos, 202 const pj_uint8_t **pkt, 203 pj_size_t *pkt_len); 204 205 /** 206 * Instruct the codec to parse a payload and append it into a picture 207 * bitstream. A picture bitstreams may need to be reconstructed from 208 * one or more payloads. Note that this function will not provide the 209 * detection of picture boundary, so application should manage the 210 * picture boundary detection by itself, e.g: for RTP delivery, payloads 211 * belong to the same picture will share the same RTP timestamp and also 212 * there is marker bit in the RTP header that is usually reserved for 213 * end-of-picture flag. 157 214 * 158 215 * @param codec The codec instance … … 168 225 * @return PJ_SUCCESS on success. 169 226 */ 170 pj_status_t (*packetize) (pjmedia_vid_codec *codec,171 pj_uint8_t *buf,172 pj_size_t buf_len,173 unsigned *pos,174 const pj_uint8_t **payload,175 pj_size_t *payload_len);176 177 /**178 * Instruct the codec to inspect the specified payload/packet and179 * split the packet into individual base frames. Each output frames will180 * have ptime that is equal to basic frame ptime (i.e. the value of181 * info.frm_ptime in #pjmedia_vid_codec_param).182 *183 * @param codec The codec instance184 * @param pkt The input packet.185 * @param pkt_size Size of the packet.186 * @param timestamp The timestamp of the first sample in the packet.187 * @param frame_cnt On input, specifies the maximum number of frames188 * in the array. On output, the codec must fill189 * with number of frames detected in the packet.190 * @param frames On output, specifies the frames that have been191 * detected in the packet.192 *193 * @return PJ_SUCCESS on success.194 */195 227 pj_status_t (*unpacketize)(pjmedia_vid_codec *codec, 196 228 const pj_uint8_t *payload, 197 229 pj_size_t payload_len, 198 pj_uint8_t *b uf,199 pj_size_t *b uf_len);230 pj_uint8_t *bits, 231 pj_size_t *bits_len); 200 232 201 233 /** 202 234 * Instruct the codec to encode the specified input frame. The input 203 * PCM samples MUST have ptime that is multiplication of base frame204 * ptime (i.e. the value of info.frm_ptime in #pjmedia_vid_codec_param).235 * MUST contain only one picture with appropriate format as specified 236 * in opening the codec. 205 237 * 206 238 * @param codec The codec instance. … … 218 250 /** 219 251 * Instruct the codec to decode the specified input frame. The input 220 * frame MUST have ptime that is exactly equal to base frame 221 * ptime (i.e. the value of info.frm_ptime in #pjmedia_vid_codec_param). 222 * Application can achieve this by parsing the packet into base 223 * frames before decoding each frame. 252 * frame MUST contain exactly one picture. Note that the decoded picture 253 * format may different to the current setting, e.g: the format specified 254 * in the #pjmedia_vid_codec_param when opening the codec, in this case the 255 * PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED flag will be set in the bit_info 256 * field of the output frame and application can query the new format 257 * using #get_param(). 224 258 * 225 259 * @param codec The codec instance. … … 248 282 unsigned out_size, 249 283 pjmedia_frame *output); 284 250 285 } pjmedia_vid_codec_op; 251 286 … … 259 294 260 295 /** 261 * This structure describes a codec instance.296 * This structure describes a video codec instance. 262 297 */ 263 298 struct pjmedia_vid_codec … … 267 302 268 303 /** Codec's private data. */ 269 void 304 void *codec_data; 270 305 271 306 /** Codec factory where this codec was allocated. */ … … 273 308 274 309 /** Operations to codec. */ 275 pjmedia_vid_codec_op 310 pjmedia_vid_codec_op *op; 276 311 }; 277 312 … … 377 412 378 413 /** 414 * Opaque declaration for codec manager. 415 */ 416 typedef struct pjmedia_vid_codec_mgr pjmedia_vid_codec_mgr; 417 418 /** 379 419 * Declare maximum codecs 380 420 */ … … 382 422 383 423 384 /** 385 * Codec manager maintains array of these structs for each supported 386 * codec. 387 */ 388 typedef struct pjmedia_vid_codec_desc 389 { 390 pjmedia_vid_codec_info info; /**< Codec info. */ 391 pjmedia_codec_id id; /**< Fully qualified name */ 392 pjmedia_codec_priority prio; /**< Priority. */ 393 pjmedia_vid_codec_factory *factory; /**< The factory. */ 394 pjmedia_vid_codec_param *def_param; /**< Default codecs 395 parameters. */ 396 } pjmedia_vid_codec_desc; 397 398 399 /** 400 * The declaration for codec manager. Application doesn't normally need 401 * to see this declaration, but nevertheless this declaration is needed 402 * by media endpoint to instantiate the codec manager. 403 */ 404 typedef struct pjmedia_vid_codec_mgr 405 { 406 /** Codec manager mutex. */ 407 pj_mutex_t *mutex; 408 409 /** List of codec factories registered to codec manager. */ 410 pjmedia_vid_codec_factory factory_list; 411 412 /** Number of supported codecs. */ 413 unsigned codec_cnt; 414 415 /** Array of codec descriptor. */ 416 pjmedia_vid_codec_desc codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS]; 417 418 } pjmedia_vid_codec_mgr; 419 420 421 422 /** 423 * Initialize codec manager. Normally this function is called by pjmedia 424 425 /** 426 * Initialize codec manager. If there is no the default video codec manager, 427 * this function will automatically set the default video codec manager to 428 * the new codec manager instance. Normally this function is called by pjmedia 424 429 * endpoint's initialization code. 425 430 * 426 * @param mgr Codec managerinstance.427 * @param pf Pool factoryinstance.431 * @param pool The pool instance. 432 * @param mgr The pointer to the new codec manager instance. 428 433 * 429 434 * @return PJ_SUCCESS on success. … … 437 442 * endpoint's deinitialization code. 438 443 * 439 * @param mgr Codec manager instance. 444 * @param mgr Codec manager instance. If NULL, it is the default codec 445 * manager instance will be destroyed. 440 446 * 441 447 * @return PJ_SUCCESS on success. … … 443 449 PJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr *mgr); 444 450 451 452 /** 453 * Get the default codec manager instance. 454 * 455 * @return The default codec manager instance or NULL if none. 456 */ 445 457 PJ_DECL(pjmedia_vid_codec_mgr*) pjmedia_vid_codec_mgr_instance(void); 458 459 460 /** 461 * Set the default codec manager instance. 462 * 463 * @param mgr The codec manager instance. 464 */ 446 465 PJ_DECL(void) pjmedia_vid_codec_mgr_set_instance(pjmedia_vid_codec_mgr* mgr); 447 466 … … 451 470 * all supported codecs in the factory to the codec manager. 452 471 * 453 * @param mgr The codec manager instance. Application can get the454 * instance by calling #pjmedia_endpt_get_codec_mgr().472 * @param mgr The codec manager instance. If NULL, the default codec 473 * manager instance will be used. 455 474 * @param factory The codec factory to be registered. 456 475 * … … 466 485 * codec manager's list of supported codecs. 467 486 * 468 * @param mgr The codec manager instance. Application can get the469 * instance by calling #pjmedia_endpt_get_codec_mgr().487 * @param mgr The codec manager instance. If NULL, the default codec 488 * manager instance will be used. 470 489 * @param factory The codec factory to be unregistered. 471 490 * … … 480 499 * codec manager by codec factories. 481 500 * 482 * @param mgr The codec manager instance. Application can get the483 * instance by calling #pjmedia_endpt_get_codec_mgr().501 * @param mgr The codec manager instance. If NULL, the default codec 502 * manager instance will be used. 484 503 * @param count On input, specifies the number of elements in 485 504 * the array. On output, the value will be set to … … 501 520 * Get codec info for the specified static payload type. 502 521 * 503 * @param mgr The codec manager instance. Application can get the504 * instance by calling #pjmedia_endpt_get_codec_mgr().522 * @param mgr The codec manager instance. If NULL, the default codec 523 * manager instance will be used. 505 524 * @param pt Static payload type/number. 506 * @param inf Pointer to receive codec info.525 * @param info Pointer to receive codec info. 507 526 * 508 527 * @return PJ_SUCCESS on success. … … 511 530 pjmedia_vid_codec_mgr_get_codec_info( pjmedia_vid_codec_mgr *mgr, 512 531 unsigned pt, 513 const pjmedia_vid_codec_info **inf );532 const pjmedia_vid_codec_info **info); 514 533 515 534 /** 516 535 * Convert codec info struct into a unique codec identifier. 517 * A codec identifier looks something like " L16/44100/2".536 * A codec identifier looks something like "H263/90000". 518 537 * 519 538 * @param info The codec info … … 532 551 * Find codecs by the unique codec identifier. This function will find 533 552 * all codecs that match the codec identifier prefix. For example, if 534 * " L16" is specified, then it will find "L16/8000/1", "L16/16000/1",553 * "H26" is specified, then it will find "H263/90000", "H264/90000", 535 554 * and so on, up to the maximum count specified in the argument. 536 555 * 537 * @param mgr The codec manager instance. Application can get the538 * instance by calling #pjmedia_endpt_get_codec_mgr().556 * @param mgr The codec manager instance. If NULL, the default codec 557 * manager instance will be used. 539 558 * @param codec_id The full codec ID or codec ID prefix. If an empty 540 559 * string is given, it will match all codecs. … … 549 568 */ 550 569 PJ_DECL(pj_status_t) 551 pjmedia_vid_codec_mgr_find_codecs_by_id( 552 553 554 555 570 pjmedia_vid_codec_mgr_find_codecs_by_id(pjmedia_vid_codec_mgr *mgr, 571 const pj_str_t *codec_id, 572 unsigned *count, 573 const pjmedia_vid_codec_info *p_info[], 574 unsigned prio[]); 556 575 557 576 … … 562 581 * priorities of all those codecs. 563 582 * 564 * @param mgr The codec manager instance. Application can get the565 * instance by calling #pjmedia_endpt_get_codec_mgr().583 * @param mgr The codec manager instance. If NULL, the default codec 584 * manager instance will be used. 566 585 * @param codec_id The full codec ID or codec ID prefix. If an empty 567 586 * string is given, it will match all codecs. … … 574 593 PJ_DECL(pj_status_t) 575 594 pjmedia_vid_codec_mgr_set_codec_priority(pjmedia_vid_codec_mgr *mgr, 576 577 595 const pj_str_t *codec_id, 596 pj_uint8_t prio); 578 597 579 598 … … 581 600 * Get default codec param for the specified codec info. 582 601 * 583 * @param mgr The codec manager instance. Application can get the584 * instance by calling #pjmedia_endpt_get_codec_mgr().602 * @param mgr The codec manager instance. If NULL, the default codec 603 * manager instance will be used. 585 604 * @param info The codec info, which default parameter's is being 586 605 * queried. … … 591 610 */ 592 611 PJ_DECL(pj_status_t) 593 pjmedia_vid_codec_mgr_get_default_param( 594 595 pjmedia_vid_codec_param *param);612 pjmedia_vid_codec_mgr_get_default_param(pjmedia_vid_codec_mgr *mgr, 613 const pjmedia_vid_codec_info *info, 614 pjmedia_vid_codec_param *param); 596 615 597 616 … … 599 618 * Set default codec param for the specified codec info. 600 619 * 601 * @param mgr The codec manager instance. Application can get the 602 * instance by calling #pjmedia_endpt_get_codec_mgr(). 620 * @param mgr The codec manager instance. If NULL, the default codec 621 * manager instance will be used. 622 * @param pool The pool instance. 603 623 * @param info The codec info, which default parameter's is being 604 624 * updated. … … 620 640 * until it finds factory that is able to create the specified codec. 621 641 * 622 * @param mgr The codec manager instance. Application can get the623 * instance by calling #pjmedia_endpt_get_codec_mgr().642 * @param mgr The codec manager instance. If NULL, the default codec 643 * manager instance will be used. 624 644 * @param info The information about the codec to be created. 625 645 * @param p_codec Pointer to receive the codec instance. … … 636 656 * the instance of the codec back to its factory. 637 657 * 638 * @param mgr The codec manager instance. Application can get the639 * instance by calling #pjmedia_endpt_get_codec_mgr().658 * @param mgr The codec manager instance. If NULL, the default codec 659 * manager instance will be used. 640 660 * @param codec The codec instance. 641 661 * … … 655 675 656 676 /** 657 * @defgroup PJMEDIA_CODEC_ CODECS Supportedcodecs677 * @defgroup PJMEDIA_CODEC_VID_CODECS Supported video codecs 658 678 * @ingroup PJMEDIA_CODEC 659 * @brief Documentation about individual codec supported by PJMEDIA679 * @brief Documentation about individual video codec supported by PJMEDIA 660 680 * @{ 661 681 * Please see the APIs provided by the individual codecs below. -
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/videoport.h
r3402 r3420 109 109 * @return The video stream. 110 110 */ 111 PJ_DECL(pjmedia_vid_ stream*)111 PJ_DECL(pjmedia_vid_dev_stream*) 112 112 pjmedia_vid_port_get_stream(pjmedia_vid_port *vid_port); 113 113 -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
r3392 r3420 28 28 #include <pj/os.h> 29 29 30 30 31 /* 31 32 * Only build this file if PJMEDIA_HAS_FFMPEG_CODEC != 0 … … 38 39 #include <libavcodec/avcodec.h> 39 40 #include <libavformat/avformat.h> 41 #include <libswscale/swscale.h> 40 42 41 43 … … 66 68 static pj_status_t ffmpeg_codec_modify(pjmedia_vid_codec *codec, 67 69 const pjmedia_vid_codec_param *attr ); 70 static pj_status_t ffmpeg_codec_get_param(pjmedia_vid_codec *codec, 71 pjmedia_vid_codec_param *param); 68 72 static pj_status_t ffmpeg_packetize ( pjmedia_vid_codec *codec, 69 73 pj_uint8_t *buf, … … 96 100 &ffmpeg_codec_close, 97 101 &ffmpeg_codec_modify, 102 &ffmpeg_codec_get_param, 98 103 &ffmpeg_packetize, 99 104 &ffmpeg_unpacketize, … … 112 117 &ffmpeg_dealloc_codec 113 118 }; 114 115 116 typedef struct ffmpeg_codec_info {117 PJ_DECL_LIST_MEMBER(struct ffmpeg_codec_info);118 pjmedia_vid_codec_info info;119 AVCodec *enc;120 AVCodec *dec;121 } ffmpeg_codec_info;122 119 123 120 … … 129 126 pj_pool_t *pool; 130 127 pj_mutex_t *mutex; 131 ffmpeg_codec_info codecs;132 128 } ffmpeg_factory; 133 129 130 131 typedef struct ffmpeg_codec_desc ffmpeg_codec_desc; 132 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 }; 134 157 135 158 /* FFMPEG codecs private data. */ 136 159 typedef struct ffmpeg_private { 160 const ffmpeg_codec_desc *desc; 161 pjmedia_vid_codec_param param; /**< Codec param */ 162 pj_pool_t *pool; /**< Pool for each instance */ 163 pj_timestamp last_tx; /**< Timestamp of last 164 transmit */ 165 166 /* Format info and apply format param */ 167 const pjmedia_video_format_info *enc_vfi; 168 pjmedia_video_apply_fmt_param enc_vafp; 169 const pjmedia_video_format_info *dec_vfi; 170 pjmedia_video_apply_fmt_param dec_vafp; 171 172 /* The ffmpeg codec states. */ 173 AVCodec *enc; 174 AVCodec *dec; 175 AVCodecContext *enc_ctx; 176 AVCodecContext *dec_ctx; 177 178 /* The ffmpeg decoder cannot set the output format, so format conversion 179 * may be needed for post-decoding. 180 */ 181 enum PixelFormat expected_dec_fmt; 182 /**< expected output format of 183 ffmpeg decoder */ 184 struct SwsContext *sws_ctx; /**< the format converter for 185 post decoding */ 186 187 } ffmpeg_private; 188 189 190 typedef pj_status_t (*func_packetize) (pj_uint8_t *buf, 191 pj_size_t buf_len, 192 unsigned *pos, 193 int max_payload_len, 194 const pj_uint8_t **payload, 195 pj_size_t *payload_len); 196 197 typedef pj_status_t (*func_unpacketize) (const pj_uint8_t *payload, 198 pj_size_t payload_len, 199 pj_uint8_t *bits, 200 pj_size_t *bits_len); 201 202 typedef pj_status_t (*func_parse_fmtp) (ffmpeg_private *ff); 203 204 /* FFMPEG codec info */ 205 struct ffmpeg_codec_desc { 206 /* Predefined info */ 207 pjmedia_vid_codec_info info; 208 func_packetize packetize; 209 func_unpacketize unpacketize; 210 func_parse_fmtp parse_fmtp; 211 pjmedia_codec_fmtp dec_fmtp; 212 213 /* Init time defined info */ 214 pj_bool_t enabled; 137 215 AVCodec *enc; 138 216 AVCodec *dec; 139 AVCodecContext *enc_ctx; 140 AVCodecContext *dec_ctx; 141 AVCodecParserContext *dec_parser_ctx; 142 143 /* 144 pjmedia_frame *pack_frms; 145 unsigned pack_frm_cnt; 146 unsigned pack_frm_max_cnt; 147 */ 148 149 pjmedia_vid_codec_param param; /**< Codec param. */ 150 pj_pool_t *pool; /**< Pool for each instance. */ 151 pj_timestamp last_tx; /**< Timestamp of last transmit.*/ 152 const pjmedia_video_format_info *vfi; 153 pjmedia_video_apply_fmt_param vafp; 154 } ffmpeg_private; 217 }; 218 219 /* H263 packetizer */ 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); 242 243 244 /* Internal codec info */ 245 ffmpeg_codec_desc codec_desc[] = 246 { 247 { 248 {PJMEDIA_FORMAT_H263, {"H263",4}, PJMEDIA_RTP_PT_H263}, 249 &h263_packetize, &h263_unpacketize, &h263_parse_fmtp, 250 {2, { {{"CIF",3}, {"2",1}}, {{"QCIF",4}, {"1",1}}, } }, 251 }, 252 { 253 {PJMEDIA_FORMAT_H261, {"H261",4}, PJMEDIA_RTP_PT_H261}, 254 }, 255 { 256 {PJMEDIA_FORMAT_MJPEG, {"JPEG",4}, PJMEDIA_RTP_PT_JPEG}, 257 }, 258 }; 259 260 /* Parse fmtp value for custom resolution, e.g: "CUSTOM=800,600,2" */ 261 static pj_status_t parse_fmtp_itu_custom_res(const pj_str_t *fmtp_val, 262 pjmedia_rect_size *size, 263 unsigned *mpi) 264 { 265 const char *p, *p_end; 266 pj_str_t token; 267 unsigned long val[3] = {0}; 268 unsigned i = 0; 269 270 p = token.ptr = fmtp_val->ptr; 271 p_end = p + fmtp_val->slen; 272 273 while (p<=p_end && i<PJ_ARRAY_SIZE(val)) { 274 if (*p==',' || p==p_end) { 275 token.slen = (char*)p - token.ptr; 276 val[i++] = pj_strtoul(&token); 277 token.ptr = (char*)p+1; 278 } 279 ++p; 280 } 281 282 if (!val[0] || !val[1]) 283 return PJ_ETOOSMALL; 284 285 if (val[2]<1 || val[2]>32) 286 return PJ_EINVAL; 287 288 size->w = val[0]; 289 size->h = val[1]; 290 *mpi = val[2]; 291 return PJ_SUCCESS; 292 } 293 294 #define CALC_ITU_CUSTOM_RES_SCORE(size, mpi) ((size)->w * (size)->h / mpi) 295 296 /* ITU codec capabilities */ 297 typedef struct itu_cap 298 { 299 /* Lowest MPI for each non-custom resolution */ 300 unsigned lowest_mpi[PJ_ARRAY_SIZE(itu_res_def)]; 301 /* For custom resolution, we use maximum processing score */ 302 unsigned custom_res_max_score; 303 } itu_cap; 304 305 306 static pj_status_t load_itu_cap(const pjmedia_codec_fmtp *fmtp, 307 itu_cap *cap) 308 { 309 unsigned i, j; 310 unsigned min_mpi = 0; 311 312 /* Get Minimum Picture Interval (MPI) for each resolution. If a resolution 313 * has no MPI setting in fmtp, the MPI setting is derived from the higher 314 * resolution. 315 */ 316 for (i=0; i<PJ_ARRAY_SIZE(itu_res_def); ++i) { 317 318 /* Init lowest MPI */ 319 cap->lowest_mpi[i] = min_mpi? min_mpi:1; 320 321 for (j=0; j<fmtp->cnt; ++j) { 322 if (pj_stricmp(&fmtp->param[j].name, &itu_res_def[i].name)==0) { 323 pjmedia_rect_size size; 324 unsigned mpi; 325 unsigned score; 326 327 if (i != ITU_RES_CUSTOM) { 328 size = itu_res_def[i].size; 329 mpi = pj_strtoul(&fmtp->param[j].val); 330 if (min_mpi) 331 min_mpi = PJ_MIN(mpi, min_mpi); 332 else 333 min_mpi = mpi; 334 335 /* Update the lowest MPI for this resolution */ 336 cap->lowest_mpi[i] = min_mpi; 337 338 /* Also update the processing score for the custom 339 * resolution. 340 */ 341 score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 342 cap->custom_res_max_score = 343 PJ_MAX(score, cap->custom_res_max_score); 344 } else { 345 346 347 if (parse_fmtp_itu_custom_res(&fmtp->param[j].val, 348 &size, &mpi) == PJ_SUCCESS) 349 { 350 score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 351 cap->custom_res_max_score = 352 PJ_MAX(score, cap->custom_res_max_score); 353 } 354 } 355 } 356 } 357 } 358 359 return PJ_SUCCESS; 360 } 361 362 /* H263 fmtp parser */ 363 static pj_status_t h263_parse_fmtp(ffmpeg_private *ff) 364 { 365 pjmedia_dir dir; 366 pj_status_t status; 367 368 dir = ff->param.dir; 369 370 if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 371 pjmedia_vid_codec_param param_ref; 372 pjmedia_codec_fmtp *fmtp_rem, *fmtp_ref; 373 itu_cap local_cap; 374 pjmedia_rect_size size = {0}; 375 unsigned mpi = 0; 376 pj_bool_t got_good_res = PJ_FALSE; 377 pj_bool_t has_prefered_res = PJ_FALSE; 378 unsigned i, j; 379 380 fmtp_rem = &ff->param.enc_fmtp; 381 dir &= ~PJMEDIA_DIR_ENCODING; 382 383 /* Get default fmtp setting as the reference for local capabilities */ 384 status = pjmedia_vid_codec_mgr_get_default_param( 385 ffmpeg_factory.mgr, &ff->desc->info, ¶m_ref); 386 fmtp_ref = (status==PJ_SUCCESS)? ¶m_ref.enc_fmtp : fmtp_rem; 387 388 /* Load default local capabilities */ 389 status = load_itu_cap(fmtp_ref, &local_cap); 390 pj_assert(status == PJ_SUCCESS); 391 392 /* Negotiate resolution and MPI */ 393 for (i=0; i<fmtp_rem->cnt && !got_good_res; ++i) 394 { 395 for (j=0; j<PJ_ARRAY_SIZE(itu_res_def) && !got_good_res; ++j) 396 { 397 if (pj_stricmp(&fmtp_rem->param[i].name, &itu_res_def[j].name)) 398 continue; 399 400 has_prefered_res = PJ_TRUE; 401 if (j == ITU_RES_CUSTOM) { 402 unsigned score; 403 404 if (parse_fmtp_itu_custom_res(&fmtp_rem->param[i].val, 405 &size, &mpi) != PJ_SUCCESS) 406 { 407 /* Invalid custom resolution format, skip this 408 * custom resolution 409 */ 410 break; 411 } 412 413 score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 414 if (score <= local_cap.custom_res_max_score) 415 got_good_res = PJ_TRUE; 416 } else { 417 mpi = pj_strtoul(&fmtp_rem->param[i].val); 418 if (mpi>=1 && mpi<=32 && mpi>=local_cap.lowest_mpi[j]) { 419 got_good_res = PJ_TRUE; 420 size = itu_res_def[j].size; 421 } 422 } 423 } 424 } 425 426 if (has_prefered_res) { 427 if (got_good_res) { 428 pjmedia_video_format_detail *vfd; 429 430 /* Apply this size & MPI */ 431 vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, 432 PJ_TRUE); 433 vfd->size = size; 434 vfd->fps.num = 30000; 435 vfd->fps.denum = 1001 * mpi; 436 got_good_res = PJ_TRUE; 437 438 PJ_TODO(NOTIFY_APP_ABOUT_THIS_NEW_ENCODING_FORMAT); 439 } else { 440 return PJ_EUNKNOWN; 441 } 442 } 443 } 444 445 return PJ_SUCCESS; 446 } 447 448 449 450 static const ffmpeg_codec_desc* find_codec_info( 451 const pjmedia_vid_codec_info *info) 452 { 453 int i; 454 455 for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) { 456 ffmpeg_codec_desc *desc = &codec_desc[i]; 457 458 if (desc->enabled && 459 (desc->info.fmt_id == info->fmt_id) && 460 ((desc->info.dir & info->dir) == info->dir) && 461 pj_stricmp(&desc->info.encoding_name, &info->encoding_name)==0) 462 { 463 return desc; 464 } 465 } 466 467 return NULL; 468 } 469 470 471 static int find_codec_info_idx_by_fmt_id(pjmedia_format_id fmt_id) 472 { 473 int i; 474 for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) { 475 if (codec_desc[i].info.fmt_id == fmt_id) 476 return i; 477 } 478 479 return -1; 480 } 155 481 156 482 … … 163 489 pj_pool_t *pool; 164 490 AVCodec *c; 165 enum CodecID last_codec_id = CODEC_ID_NONE;166 491 pj_status_t status; 167 492 … … 179 504 ffmpeg_factory.mgr = mgr; 180 505 ffmpeg_factory.pf = pf; 181 pj_list_init(&ffmpeg_factory.codecs);182 506 183 507 pool = pj_pool_create(pf, "ffmpeg codec factory", 256, 256, NULL); … … 197 521 for (c=av_codec_next(NULL); c; c=av_codec_next(c)) 198 522 { 199 ffmpeg_codec_info *ci; 523 ffmpeg_codec_desc *desc; 524 pjmedia_format_id fmt_id; 525 int codec_info_idx; 200 526 201 527 if (c->type != CODEC_TYPE_VIDEO) … … 203 529 204 530 /* Video encoder and decoder are usually implemented in separate 205 * AVCodec instances. 531 * AVCodec instances. While the codec attributes (e.g: raw formats, 532 * supported fps) are in the encoder. 206 533 */ 207 534 208 if (c->id == last_codec_id) { 209 /* This codec usually be the decoder, and not as much info as in 210 * encoder can be fetched here. 211 */ 212 pj_assert(!pj_list_empty(&ffmpeg_factory.codecs)); 213 ci = ffmpeg_factory.codecs.prev; 214 pj_assert(ci->info.dir != PJMEDIA_DIR_ENCODING_DECODING); 215 pj_assert(!ci->dec || !ci->enc); 216 } else { 217 pjmedia_format_id enc_fmt_id; 218 pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT]; 219 unsigned raw_fmt_cnt = 0; 220 unsigned raw_fmt_cnt_should_be = 0; 221 222 /* Get encoded format id */ 223 status = CodecID_to_pjmedia_format_id(c->id, &enc_fmt_id); 224 if (status != PJ_SUCCESS) { 225 //PJ_LOG(5, (THIS_FILE, "Unrecognized ffmpeg codec id %d, " 226 // "codec [%s/%s] ignored", 227 // c->id, c->name, c->long_name)); 228 //enc_fmt_id = PJMEDIA_FORMAT_FFMPEG_UNKNOWN; 229 230 /* Skip unrecognized encoding format ID */ 231 continue; 232 } 233 234 /* Get raw/decoded format ids */ 235 if (c->pix_fmts) { 236 const enum PixelFormat *p = c->pix_fmts; 237 for(;(p && *p != -1) && 238 (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT); 239 ++p) 240 { 241 pjmedia_format_id fmt_id; 242 243 raw_fmt_cnt_should_be++; 244 status = PixelFormat_to_pjmedia_format_id(*p, &fmt_id); 245 if (status != PJ_SUCCESS) { 246 PJ_LOG(6, (THIS_FILE, "Unrecognized ffmpeg pixel " 247 "format %d", *p)); 248 continue; 249 } 250 raw_fmt[raw_fmt_cnt++] = fmt_id; 251 } 252 } else { 253 /* Unknown raw format, ignore this codec? */ 254 continue; 255 } 256 257 if (raw_fmt_cnt < raw_fmt_cnt_should_be) { 258 PJ_LOG(6, (THIS_FILE, "Codec [%s/%s] have %d raw formats, " 259 "recognized only %d raw formats", 260 c->name, c->long_name, 261 raw_fmt_cnt_should_be, raw_fmt_cnt)); 262 } 263 if (raw_fmt_cnt == 0) { 264 PJ_LOG(5, (THIS_FILE, "No recognized raw format " 265 "for codec [%s/%s], codec ignored", 266 c->name, c->long_name)); 267 /* Comment this to see all ffmpeg codecs */ 268 continue; 269 } 270 271 ci = PJ_POOL_ZALLOC_T(pool, ffmpeg_codec_info); 272 ci->info.fmt_id = enc_fmt_id; 273 pj_cstr(&ci->info.encoding_name, c->name); 274 ci->info.clock_rate = 90000; 275 ci->info.dec_fmt_id_cnt = raw_fmt_cnt; 276 pj_memcpy(ci->info.dec_fmt_id, raw_fmt, 277 sizeof(raw_fmt[0])*raw_fmt_cnt); 278 279 switch (enc_fmt_id) { 280 case PJMEDIA_FORMAT_H263: 281 ci->info.pt = PJMEDIA_RTP_PT_H263; 282 break; 283 case PJMEDIA_FORMAT_H261: 284 ci->info.pt = PJMEDIA_RTP_PT_H261; 285 break; 286 default: 287 break; 288 } 289 290 if (c->supported_framerates) { 291 const AVRational *fr = c->supported_framerates; 292 while ((fr->num != 0 || fr->den != 0) && 293 ci->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT) 294 { 295 ci->info.fps[ci->info.fps_cnt].num = fr->num; 296 ci->info.fps[ci->info.fps_cnt].denum = fr->den; 297 ++ci->info.fps_cnt; 298 ++fr; 299 } 300 } 301 302 pj_list_push_back(&ffmpeg_factory.codecs, ci); 535 status = CodecID_to_pjmedia_format_id(c->id, &fmt_id); 536 /* Skip if format ID is unknown */ 537 if (status != PJ_SUCCESS) 538 continue; 539 540 codec_info_idx = find_codec_info_idx_by_fmt_id(fmt_id); 541 /* Skip if codec is unwanted by this wrapper (not listed in 542 * the codec info array) 543 */ 544 if (codec_info_idx < 0) 545 continue; 546 547 desc = &codec_desc[codec_info_idx]; 548 549 /* Skip duplicated codec implementation */ 550 if ((c->encode && (desc->info.dir & PJMEDIA_DIR_ENCODING)) || 551 (c->decode && (desc->info.dir & PJMEDIA_DIR_DECODING))) 552 { 553 continue; 554 } 555 556 /* Get raw/decoded format ids in the encoder */ 557 if (c->pix_fmts && c->encode) { 558 pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT]; 559 unsigned raw_fmt_cnt = 0; 560 unsigned raw_fmt_cnt_should_be = 0; 561 const enum PixelFormat *p = c->pix_fmts; 562 563 for(;(p && *p != -1) && 564 (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT); 565 ++p) 566 { 567 pjmedia_format_id fmt_id; 568 569 raw_fmt_cnt_should_be++; 570 status = PixelFormat_to_pjmedia_format_id(*p, &fmt_id); 571 if (status != PJ_SUCCESS) { 572 PJ_LOG(6, (THIS_FILE, "Unrecognized ffmpeg pixel " 573 "format %d", *p)); 574 continue; 575 } 576 raw_fmt[raw_fmt_cnt++] = fmt_id; 577 } 578 579 if (raw_fmt_cnt == 0) { 580 PJ_LOG(5, (THIS_FILE, "No recognized raw format " 581 "for codec [%s/%s], codec ignored", 582 c->name, c->long_name)); 583 /* Skip this encoder */ 584 continue; 585 } 586 587 if (raw_fmt_cnt < raw_fmt_cnt_should_be) { 588 PJ_LOG(6, (THIS_FILE, "Codec [%s/%s] have %d raw formats, " 589 "recognized only %d raw formats", 590 c->name, c->long_name, 591 raw_fmt_cnt_should_be, raw_fmt_cnt)); 592 } 593 594 desc->info.dec_fmt_id_cnt = raw_fmt_cnt; 595 pj_memcpy(desc->info.dec_fmt_id, raw_fmt, 596 sizeof(raw_fmt[0])*raw_fmt_cnt); 597 } 598 599 /* Get supported framerates */ 600 if (c->supported_framerates) { 601 const AVRational *fr = c->supported_framerates; 602 while ((fr->num != 0 || fr->den != 0) && 603 desc->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT) 604 { 605 desc->info.fps[desc->info.fps_cnt].num = fr->num; 606 desc->info.fps[desc->info.fps_cnt].denum = fr->den; 607 ++desc->info.fps_cnt; 608 ++fr; 609 } 610 } 611 612 /* Get ffmpeg encoder instance */ 613 if (c->encode && !desc->enc) { 614 desc->info.dir |= PJMEDIA_DIR_ENCODING; 615 desc->enc = c; 303 616 } 304 305 if (c->encode) { 306 ci->info.dir |= PJMEDIA_DIR_ENCODING; 307 ci->enc = c; 617 618 /* Get ffmpeg decoder instance */ 619 if (c->decode && !desc->dec) { 620 desc->info.dir |= PJMEDIA_DIR_DECODING; 621 desc->dec = c; 308 622 } 309 if (c->decode) { 310 ci->info.dir |= PJMEDIA_DIR_DECODING; 311 ci->dec = c; 312 } 313 314 last_codec_id = c->id; 623 624 /* Enable this codec when any ffmpeg codec instance are recognized 625 * and the supported raw formats info has been collected. 626 */ 627 if ((desc->dec || desc->enc) && desc->info.dec_fmt_id_cnt) 628 { 629 desc->enabled = PJ_TRUE; 630 } 631 632 /* Normalize default value of clock rate */ 633 if (desc->info.clock_rate == 0) 634 desc->info.clock_rate = 90000; 315 635 } 316 636 … … 360 680 361 681 362 static ffmpeg_codec_info* find_codec(const pjmedia_vid_codec_info *info)363 {364 ffmpeg_codec_info *ci = ffmpeg_factory.codecs.next;365 366 pj_mutex_lock(ffmpeg_factory.mutex);367 368 while (ci != &ffmpeg_factory.codecs) {369 if ((ci->info.fmt_id == info->fmt_id) &&370 ((ci->info.dir & info->dir) == info->dir) &&371 pj_stricmp(&ci->info.encoding_name, &info->encoding_name)==0)372 {373 pj_mutex_unlock(ffmpeg_factory.mutex);374 return ci;375 }376 ci = ci->next;377 }378 379 pj_mutex_unlock(ffmpeg_factory.mutex);380 381 return NULL;382 }383 384 385 682 /* 386 683 * Check if factory can allocate the specified codec. … … 389 686 const pjmedia_vid_codec_info *info ) 390 687 { 391 ffmpeg_codec_info *ci;688 const ffmpeg_codec_desc *desc; 392 689 393 690 PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL); 394 691 PJ_ASSERT_RETURN(info, PJ_EINVAL); 395 692 396 ci = find_codec(info);397 if (! ci) {693 desc = find_codec_info(info); 694 if (!desc) { 398 695 return PJMEDIA_CODEC_EUNSUP; 399 696 } … … 409 706 pjmedia_vid_codec_param *attr ) 410 707 { 411 ffmpeg_codec_info *ci;708 const ffmpeg_codec_desc *desc; 412 709 413 710 PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL); 414 711 PJ_ASSERT_RETURN(info && attr, PJ_EINVAL); 415 712 416 ci = find_codec(info);417 if (! ci) {713 desc = find_codec_info(info); 714 if (!desc) { 418 715 return PJMEDIA_CODEC_EUNSUP; 419 716 } 420 717 421 718 pj_bzero(attr, sizeof(pjmedia_vid_codec_param)); 422 attr->dir = ci->info.dir; 423 attr->pt = info->pt; 424 pjmedia_format_init_video(&attr->enc_fmt, ci->info.fmt_id, 425 352, 288, 25, 1); 426 pjmedia_format_init_video(&attr->dec_fmt, ci->info.dec_fmt_id[0], 427 352, 288, 25, 1); 719 720 /* Direction */ 721 attr->dir = desc->info.dir; 722 723 /* Encoded format */ 724 pjmedia_format_init_video(&attr->enc_fmt, desc->info.fmt_id, 725 352, 288, 30000, 1001); 726 727 /* Decoded format */ 728 pjmedia_format_init_video(&attr->dec_fmt, desc->info.dec_fmt_id[0], 729 352, 288, 30000, 1001); 730 731 /* Decoding fmtp */ 732 attr->dec_fmtp = desc->dec_fmtp; 428 733 429 734 return PJ_SUCCESS; … … 437 742 pjmedia_vid_codec_info codecs[]) 438 743 { 439 ffmpeg_codec_info *ci; 440 unsigned max; 744 unsigned i; 441 745 442 746 PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL); 443 747 PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL); 444 748 445 max = *count; 446 *count = 0; 447 ci = ffmpeg_factory.codecs.next; 448 449 pj_mutex_lock(ffmpeg_factory.mutex); 450 while (*count < max && ci != &ffmpeg_factory.codecs) { 451 pj_memcpy(&codecs[*count], &ci->info, sizeof(pjmedia_vid_codec_info)); 452 *count = *count + 1; 453 ci = ci->next; 454 } 455 pj_mutex_unlock(ffmpeg_factory.mutex); 749 *count = PJ_MIN(*count, PJ_ARRAY_SIZE(codec_desc)); 750 751 for (i=0; i<*count; ++i) { 752 pj_memcpy(&codecs[i], &codec_desc[i].info, 753 sizeof(pjmedia_vid_codec_info)); 754 } 456 755 457 756 return PJ_SUCCESS; … … 466 765 { 467 766 ffmpeg_private *ff; 468 ffmpeg_codec_info *ci;767 const ffmpeg_codec_desc *desc; 469 768 pjmedia_vid_codec *codec; 470 769 pj_pool_t *pool = NULL; … … 474 773 PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL); 475 774 476 ci = find_codec(info);477 if (! ci) {775 desc = find_codec_info(info); 776 if (!desc) { 478 777 return PJMEDIA_CODEC_EUNSUP; 479 778 } … … 495 794 codec->codec_data = ff; 496 795 ff->pool = pool; 497 ff->enc = ci->enc; 498 ff->dec = ci->dec; 796 ff->enc = desc->enc; 797 ff->dec = desc->dec; 798 ff->desc = desc; 499 799 500 800 *p_codec = codec; … … 551 851 } 552 852 553 /* 554 static enum PixelFormat ffdec_nego_format(struct AVCodecContext *s, 853 static enum PixelFormat dec_get_format(struct AVCodecContext *s, 555 854 const enum PixelFormat * fmt) 556 855 { 557 enum PixelFormat pix_fmt;558 559 PJ_UNUSED_ARG(s); 560 PJ_UNUSED_ARG(fmt);561 562 pjmedia_format_id_to_PixelFormat(PJMEDIA_FORMAT_BGRA, &pix_fmt);563 return pix_fmt;564 }565 566 static void enc_got_payload(struct AVCodecContext *avctx, 567 void *data, int size, int mb_nb);568 */ 856 ffmpeg_private *ff = (ffmpeg_private*)s->opaque; 857 enum PixelFormat def_fmt = *fmt; 858 859 while (*fmt != -1) { 860 if (*fmt == ff->expected_dec_fmt) 861 return *fmt; 862 ++fmt; 863 } 864 865 pj_assert(!"Inconsistency in supported formats"); 866 return def_fmt; 867 } 569 868 570 869 … … 574 873 enum PixelFormat pix_fmt; 575 874 pj_status_t status; 875 pjmedia_video_format_detail *vfd; 576 876 577 877 status = pjmedia_format_id_to_PixelFormat(ff->param.dec_fmt.id, … … 579 879 if (status != PJ_SUCCESS) 580 880 return status; 881 882 vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, 883 PJ_TRUE); 884 ff->expected_dec_fmt = pix_fmt; 581 885 582 886 while (((ff->param.dir & PJMEDIA_DIR_ENCODING) && ff->enc_ctx == NULL) || … … 595 899 } 596 900 901 /* Init ffmpeg codec context */ 597 902 ctx = avcodec_alloc_context(); 598 903 599 904 /* Common attributes */ 600 905 ctx->pix_fmt = pix_fmt; 601 ctx->width = ff->param.enc_fmt.det.vid.size.w;602 ctx->height = ff->param.enc_fmt.det.vid.size.h;603 906 ctx->workaround_bugs = FF_BUG_AUTODETECT; 604 907 ctx->opaque = ff; … … 608 911 609 912 /* Encoding only attributes */ 610 ctx->time_base.num = ff->param.enc_fmt.det.vid.fps.denum; 611 ctx->time_base.den = ff->param.enc_fmt.det.vid.fps.num; 612 if (ff->param.enc_fmt.det.vid.avg_bps) 613 ctx->bit_rate = ff->param.enc_fmt.det.vid.avg_bps; 614 if (ff->param.enc_fmt.det.vid.max_bps) 615 ctx->rc_max_rate = ff->param.enc_fmt.det.vid.max_bps; 616 #if 0 617 if (ff->param.enc_mtu) { 618 //ctx->rtp_payload_size = ff->param.enc_mtu; 619 //ctx->rtp_callback = &enc_got_payload; 620 621 /* Allocate frame array for RTP payload packing */ 622 if (ff->param.enc_fmt.det.vid.max_bps) 623 ff->pack_frm_max_cnt = ff->param.enc_fmt.det.vid.max_bps / 624 ff->param.enc_mtu + 1; 625 else 626 ff->pack_frm_max_cnt = 32; 627 628 ff->pack_frms = (pjmedia_frame*) 629 pj_pool_calloc(ff->pool, ff->pack_frm_max_cnt, 630 sizeof(ff->pack_frms[0])); 631 } 632 #endif 633 634 /* For encoder, should be better to be strict to the standards */ 913 ctx->width = vfd->size.w; 914 ctx->height = vfd->size.h; 915 ctx->time_base.num = vfd->fps.denum; 916 ctx->time_base.den = vfd->fps.num; 917 if (vfd->avg_bps) 918 ctx->bit_rate = vfd->avg_bps; 919 if (vfd->max_bps) 920 ctx->rc_max_rate = vfd->max_bps; 921 922 /* For encoder, should be better to be strict to the standards */ 635 923 ctx->strict_std_compliance = FF_COMPLIANCE_STRICT; 636 924 } 925 637 926 if (dir & PJMEDIA_DIR_DECODING) { 638 927 codec = ff->dec; 639 928 640 929 /* Decoding only attributes */ 641 ctx->coded_width = ctx->width; 642 ctx->coded_height = ctx->height; 930 // this setting will be automatically fetched from the bitstream. 931 //ctx->coded_width = ff->param.dec_fmt.det.vid.size.w; 932 //ctx->coded_height = ff->param.dec_fmt.det.vid.size.h; 643 933 644 934 /* For decoder, be more flexible */ 645 if (ff->param.dir!=PJMEDIA_DIR_ENCODING_DECODING || ff->enc!=ff->dec) 935 if (ff->param.dir!=PJMEDIA_DIR_ENCODING_DECODING || 936 ff->enc!=ff->dec) 937 { 646 938 ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; 647 648 //ctx->get_format = &ffdec_nego_format; 939 } 940 941 ctx->get_format = &dec_get_format; 649 942 } 650 943 … … 680 973 ff = (ffmpeg_private*)codec->codec_data; 681 974 682 ff->vfi = pjmedia_get_video_format_info(NULL, attr->dec_fmt.id);683 if (!ff->vfi) {684 status = PJ_EINVAL;685 goto on_error;686 }687 688 pj_bzero(&ff->vafp, sizeof(ff->vafp));689 ff->vafp.size = attr->dec_fmt.det.vid.size;690 ff->vafp.buffer = 0;691 status = (*ff->vfi->apply_fmt)(ff->vfi, &ff->vafp);692 if (status != PJ_SUCCESS) {693 goto on_error;694 }695 696 975 pj_memcpy(&ff->param, attr, sizeof(*attr)); 697 976 977 /* Apply SDP fmtp attribute */ 978 if (ff->desc->parse_fmtp) { 979 status = (*ff->desc->parse_fmtp)(ff); 980 if (status != PJ_SUCCESS) 981 goto on_error; 982 } 983 984 /* Open the codec */ 698 985 ff_mutex = ((struct ffmpeg_factory*)codec->factory)->mutex; 699 986 status = open_ffmpeg_codec(ff, ff_mutex); … … 701 988 goto on_error; 702 989 990 /* Init format info and apply-param of decoder */ 991 ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id); 992 if (!ff->dec_vfi) { 993 status = PJ_EINVAL; 994 goto on_error; 995 } 996 pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp)); 997 ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size; 998 ff->dec_vafp.buffer = NULL; 999 status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp); 1000 if (status != PJ_SUCCESS) { 1001 goto on_error; 1002 } 1003 1004 /* Init format info and apply-param of encoder */ 1005 ff->enc_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id); 1006 if (!ff->enc_vfi) { 1007 status = PJ_EINVAL; 1008 goto on_error; 1009 } 1010 pj_bzero(&ff->enc_vafp, sizeof(ff->enc_vafp)); 1011 ff->enc_vafp.size = ff->param.enc_fmt.det.vid.size; 1012 ff->enc_vafp.buffer = NULL; 1013 status = (*ff->enc_vfi->apply_fmt)(ff->enc_vfi, &ff->enc_vafp); 1014 if (status != PJ_SUCCESS) { 1015 goto on_error; 1016 } 1017 1018 /* Update codec attributes, e.g: encoding format may be changed by 1019 * SDP fmtp negotiation. 1020 */ 1021 pj_memcpy(attr, &ff->param, sizeof(*attr)); 1022 703 1023 return PJ_SUCCESS; 704 1024 … … 729 1049 av_free(ff->dec_ctx); 730 1050 } 731 if (ff->dec_parser_ctx) { 732 av_parser_close(ff->dec_parser_ctx); 733 1051 if (ff->sws_ctx) { 1052 sws_freeContext(ff->sws_ctx); 734 1053 } 735 1054 ff->enc_ctx = NULL; 736 1055 ff->dec_ctx = NULL; 737 ff-> dec_parser_ctx = NULL;1056 ff->sws_ctx = NULL; 738 1057 pj_mutex_unlock(ff_mutex); 739 1058 … … 746 1065 */ 747 1066 static pj_status_t ffmpeg_codec_modify( pjmedia_vid_codec *codec, 748 const pjmedia_vid_codec_param *attr 1067 const pjmedia_vid_codec_param *attr) 749 1068 { 750 1069 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; … … 755 1074 return PJ_ENOTSUP; 756 1075 } 1076 1077 static pj_status_t ffmpeg_codec_get_param(pjmedia_vid_codec *codec, 1078 pjmedia_vid_codec_param *param) 1079 { 1080 ffmpeg_private *ff; 1081 1082 PJ_ASSERT_RETURN(codec && param, PJ_EINVAL); 1083 1084 ff = (ffmpeg_private*)codec->codec_data; 1085 pj_memcpy(param, &ff->param, sizeof(*param)); 1086 1087 return PJ_SUCCESS; 1088 } 1089 757 1090 758 1091 static pj_status_t ffmpeg_packetize ( pjmedia_vid_codec *codec, … … 765 1098 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 766 1099 767 switch (ff->param.enc_fmt.id) { 768 case PJMEDIA_FORMAT_H263: 769 return pjmedia_h263_packetize(buf, buf_len, pos, 770 ff->param.enc_mtu, payload, 771 payload_len); 772 break; 773 default: 774 return PJ_ENOTSUP; 775 } 1100 if (ff->desc->packetize) { 1101 return (*ff->desc->packetize)(buf, buf_len, pos, 1102 ff->param.enc_mtu, payload, 1103 payload_len); 1104 } 1105 1106 return PJ_ENOTSUP; 776 1107 } 777 1108 … … 784 1115 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 785 1116 786 switch (ff->param.enc_fmt.id) { 787 case PJMEDIA_FORMAT_H263: 788 return pjmedia_h263_unpacketize(payload, payload_len, 789 buf, buf_len); 790 break; 791 default: 792 return PJ_ENOTSUP; 793 } 794 } 795 796 #if 0 797 /* 798 * Pack encoded frame to RTP payload frames. 799 */ 800 static pj_status_t ffmpeg_codec_pack ( pjmedia_vid_codec *codec, 801 const pjmedia_frame *enc_frame, 802 unsigned *frame_cnt, 803 pjmedia_frame frames[]) 804 { 805 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 806 unsigned i; 807 808 /* Can only work when encoding MTU is set */ 809 PJ_ASSERT_RETURN(ff->param.enc_mtu, PJ_EINVALIDOP); 810 811 /* Validate available payload number */ 812 PJ_ASSERT_RETURN(ff->pack_frm_cnt <= *frame_cnt, PJ_EINVALIDOP); 813 814 /* Validate encoded bitstream */ 815 PJ_ASSERT_RETURN(ff->pack_frm_cnt==0 || 816 ff->pack_frms[0].buf == enc_frame->buf, 817 PJ_EINVAL); 818 819 /* Return the payloads */ 820 *frame_cnt = ff->pack_frm_cnt; 821 for (i = 0; i < *frame_cnt; ++i) 822 frames[i] = ff->pack_frms[i]; 823 824 return PJ_SUCCESS; 825 } 826 827 /* 828 * Get frames in the packet. 829 */ 830 static pj_status_t ffmpeg_codec_parse( pjmedia_vid_codec *codec, 831 void *pkt, 832 pj_size_t pkt_size, 833 const pj_timestamp *ts, 834 pjmedia_frame *frame) 835 { 836 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 837 pj_uint8_t *buf = frame->buf; 838 int buf_size = frame->size; 839 int processed; 840 841 842 if (!ff->dec_parser_ctx) { 843 ff->dec_parser_ctx = av_parser_init(ff->dec->id); 844 if (!ff->dec_parser_ctx) 845 return PJ_ENOTSUP; 846 } 847 848 #if LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72 849 processed = av_parser_parse2(ff->dec_parser_ctx, ff->dec_ctx, 850 &buf, &buf_size, (uint8_t*)pkt, pkt_size, 851 ts->u64, ts->u64, AV_NOPTS_VALUE); 852 #else 853 processed = av_parser_parse (ff->dec_parser_ctx, ff->dec_ctx, 854 &buf, &buf_size, (uint8_t*)pkt, pkt_size, 855 ts->u64, ts->u64); 856 #endif 857 858 if (buf_size) { 859 frame->timestamp = *ts; 860 frame->size = buf_size; 861 return PJ_SUCCESS; 862 } 863 864 return PJ_EPENDING; 865 } 866 867 static void enc_got_payload(struct AVCodecContext *avctx, 868 void *data, int size, int mb_nb) 869 { 870 ffmpeg_private *ff = (ffmpeg_private*) avctx->opaque; 871 pjmedia_frame *payload; 872 873 pj_assert(ff->pack_frm_cnt < ff->pack_frm_max_cnt); 874 payload = &ff->pack_frms[ff->pack_frm_cnt++]; 875 payload->buf = data; 876 payload->size = size; 877 payload->bit_info = mb_nb; 878 } 879 880 #endif 1117 if (ff->desc->unpacketize) { 1118 return (*ff->desc->unpacketize)(payload, payload_len, 1119 buf, buf_len); 1120 } 1121 1122 return PJ_ENOTSUP; 1123 } 881 1124 882 1125 … … 885 1128 */ 886 1129 static pj_status_t ffmpeg_codec_encode( pjmedia_vid_codec *codec, 887 const structpjmedia_frame *input,1130 const pjmedia_frame *input, 888 1131 unsigned output_buf_len, 889 structpjmedia_frame *output)1132 pjmedia_frame *output) 890 1133 { 891 1134 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; … … 900 1143 PJ_ASSERT_RETURN(ff->enc_ctx, PJ_EINVALIDOP); 901 1144 902 /*903 ff->pack_frm_cnt = 0;904 */905 1145 avcodec_get_frame_defaults(&avframe); 906 1146 907 for (i = 0; i < ff-> vfi->plane_cnt; ++i) {1147 for (i = 0; i < ff->enc_vfi->plane_cnt; ++i) { 908 1148 avframe.data[i] = p; 909 avframe.linesize[i] = ff-> vafp.strides[i];910 p += ff-> vafp.plane_bytes[i];1149 avframe.linesize[i] = ff->enc_vafp.strides[i]; 1150 p += ff->enc_vafp.plane_bytes[i]; 911 1151 } 912 1152 … … 946 1186 */ 947 1187 static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec, 948 const structpjmedia_frame *input,1188 const pjmedia_frame *input, 949 1189 unsigned output_buf_len, 950 structpjmedia_frame *output)1190 pjmedia_frame *output) 951 1191 { 952 1192 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; … … 958 1198 PJ_ASSERT_RETURN(ff->dec_ctx, PJ_EINVALIDOP); 959 1199 960 PJ_UNUSED_ARG(output_buf_len); 1200 /* Validate output buffer size */ 1201 PJ_ASSERT_RETURN(ff->dec_vafp.framebytes <= output_buf_len, PJ_ETOOSMALL); 961 1202 962 1203 /* Init frame to receive the decoded data, the ffmpeg codec context will … … 979 1220 */ 980 1221 pj_bzero(avpacket.data+avpacket.size, FF_INPUT_BUFFER_PADDING_SIZE); 1222 1223 output->bit_info = 0; 981 1224 982 1225 #if LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72 … … 997 1240 return PJ_EUNKNOWN; 998 1241 } else if (got_picture) { 999 pjmedia_video_apply_fmt_param *vafp = (pjmedia_video_apply_fmt_param*) 1000 &ff->vafp; 1242 pjmedia_video_apply_fmt_param *vafp = &ff->dec_vafp; 1001 1243 pj_uint8_t *q = (pj_uint8_t*)output->buf; 1002 unsigned i; 1003 1004 /* Get the decoded data */ 1005 for (i = 0; i < ff->vfi->plane_cnt; ++i) { 1006 pj_uint8_t *p = avframe.data[i]; 1007 1008 /* The decoded data may contain padding */ 1009 if (avframe.linesize[i]==vafp->strides[i]) { 1010 /* No padding, copy the whole plane */ 1011 pj_memcpy(q, p, vafp->plane_bytes[i]); 1012 q += vafp->plane_bytes[i]; 1013 } else { 1014 /* Padding exists, copy line by line */ 1015 pj_uint8_t *q_end; 1016 1017 q_end = q+vafp->plane_bytes[i]; 1018 while(q < q_end) { 1019 pj_memcpy(q, p, vafp->strides[i]); 1020 q += vafp->strides[i]; 1021 p += avframe.linesize[i]; 1022 } 1023 } 1024 } 1244 unsigned i; 1245 1246 /* Decoder output format is set by libavcodec, in case it is different 1247 * to the configured param. 1248 */ 1249 if (ff->dec_ctx->pix_fmt != ff->expected_dec_fmt || 1250 ff->dec_ctx->coded_width != (int)vafp->size.w || 1251 ff->dec_ctx->coded_height != (int)vafp->size.h) 1252 { 1253 #if 0 1254 // it should not be the codec responsibility to do resizing 1255 pj_uint8_t *data[PJMEDIA_MAX_VIDEO_PLANES] = {0}; 1256 unsigned i; 1257 int h; 1258 1259 if (!ff->sws_ctx) { 1260 pj_assert(sws_isSupportedInput(ff->dec_ctx->pix_fmt) > 0); 1261 pj_assert(sws_isSupportedOutput(ff->expected_dec_fmt) > 0); 1262 ff->sws_ctx = sws_getContext(ff->dec_ctx->coded_width, 1263 ff->dec_ctx->coded_height, 1264 ff->dec_ctx->pix_fmt, 1265 vafp->size.w, vafp->size.h, 1266 ff->expected_dec_fmt, 1267 SWS_BILINEAR | SWS_PRINT_INFO, 1268 NULL, NULL, NULL); 1269 if (ff->sws_ctx == NULL) { 1270 return PJ_EUNKNOWN; 1271 } 1272 } 1273 1274 for (i = 0; i < ff->vfi->plane_cnt; ++i) { 1275 data[i] = q; 1276 q += vafp->plane_bytes[i]; 1277 } 1278 h = sws_scale(ff->sws_ctx, avframe.data, avframe.linesize, 0, 1279 ff->dec_ctx->coded_height, data, vafp->strides); 1280 pj_assert((int)vafp->size.h == h); 1281 #endif 1282 1283 pjmedia_format_id new_fmt_id; 1284 pj_status_t status; 1285 1286 /* Get current raw format id from ffmpeg decoder context */ 1287 status = PixelFormat_to_pjmedia_format_id(ff->dec_ctx->pix_fmt, 1288 &new_fmt_id); 1289 if (status != PJ_SUCCESS) 1290 return status; 1291 1292 /* Update decoder format in param */ 1293 ff->param.dec_fmt.id = new_fmt_id; 1294 ff->param.dec_fmt.det.vid.size.w = ff->dec_ctx->coded_width; 1295 ff->param.dec_fmt.det.vid.size.h = ff->dec_ctx->coded_height; 1296 1297 /* Re-init format info and apply-param of decoder */ 1298 ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id); 1299 if (!ff->dec_vfi) 1300 return PJ_EUNKNOWN; 1301 pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp)); 1302 ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size; 1303 ff->dec_vafp.buffer = NULL; 1304 status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp); 1305 if (status != PJ_SUCCESS) 1306 return status; 1307 1308 /* Notify application via the bit_info field of pjmedia_frame */ 1309 output->bit_info = PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED; 1310 } 1311 1312 /* Check provided buffer size after format changed */ 1313 if (vafp->framebytes > output_buf_len) 1314 return PJ_ETOOSMALL; 1315 1316 /* Get the decoded data */ 1317 for (i = 0; i < ff->dec_vfi->plane_cnt; ++i) { 1318 pj_uint8_t *p = avframe.data[i]; 1319 1320 /* The decoded data may contain padding */ 1321 if (avframe.linesize[i]!=vafp->strides[i]) { 1322 /* Padding exists, copy line by line */ 1323 pj_uint8_t *q_end; 1324 1325 q_end = q+vafp->plane_bytes[i]; 1326 while(q < q_end) { 1327 pj_memcpy(q, p, vafp->strides[i]); 1328 q += vafp->strides[i]; 1329 p += avframe.linesize[i]; 1330 } 1331 } else { 1332 /* No padding, copy the whole plane */ 1333 pj_memcpy(q, p, vafp->plane_bytes[i]); 1334 q += vafp->plane_bytes[i]; 1335 } 1336 } 1337 1025 1338 output->size = vafp->framebytes; 1026 1339 } else { … … 1036 1349 static pj_status_t ffmpeg_codec_recover( pjmedia_vid_codec *codec, 1037 1350 unsigned output_buf_len, 1038 struct pjmedia_frame *output) 1039 { 1040 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 1041 1351 pjmedia_frame *output) 1352 { 1353 PJ_UNUSED_ARG(codec); 1042 1354 PJ_UNUSED_ARG(output_buf_len); 1043 1355 PJ_UNUSED_ARG(output); 1044 PJ_UNUSED_ARG(ff); 1045 1046 return PJ_SUCCESS; 1356 1357 return PJ_ENOTSUP; 1047 1358 } 1048 1359 1049 1360 #ifdef _MSC_VER 1050 1361 # pragma comment( lib, "avcodec.lib") 1362 # pragma comment( lib, "swscale.lib") 1051 1363 #endif 1052 1364 -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/colorbar_dev.c
r3401 r3420 81 81 struct cbar_stream 82 82 { 83 pjmedia_vid_ stream base; /**< Base stream*/84 pjmedia_vid_param param; /**< Settings*/85 pj_pool_t *pool; /**< Memory pool.*/86 87 pjmedia_vid_cb vid_cb; /**< Stream callback.*/88 void *user_data; /**< Application data.*/83 pjmedia_vid_dev_stream base; /**< Base stream */ 84 pjmedia_vid_param param; /**< Settings */ 85 pj_pool_t *pool; /**< Memory pool. */ 86 87 pjmedia_vid_cb vid_cb; /**< Stream callback. */ 88 void *user_data; /**< Application data. */ 89 89 90 90 const struct cbar_fmt_info *cbfi; … … 106 106 unsigned index, 107 107 pjmedia_vid_param *param); 108 static pj_status_t cbar_factory_create_stream(pjmedia_vid_dev_factory *f, 109 const pjmedia_vid_param *param, 110 const pjmedia_vid_cb *cb, 111 void *user_data, 112 pjmedia_vid_stream **p_vid_strm); 113 114 static pj_status_t cbar_stream_get_param(pjmedia_vid_stream *strm, 108 static pj_status_t cbar_factory_create_stream( 109 pjmedia_vid_dev_factory *f, 110 const pjmedia_vid_param *param, 111 const pjmedia_vid_cb *cb, 112 void *user_data, 113 pjmedia_vid_dev_stream **p_vid_strm); 114 115 static pj_status_t cbar_stream_get_param(pjmedia_vid_dev_stream *strm, 115 116 pjmedia_vid_param *param); 116 static pj_status_t cbar_stream_get_cap(pjmedia_vid_ stream *strm,117 static pj_status_t cbar_stream_get_cap(pjmedia_vid_dev_stream *strm, 117 118 pjmedia_vid_dev_cap cap, 118 119 void *value); 119 static pj_status_t cbar_stream_set_cap(pjmedia_vid_ stream *strm,120 static pj_status_t cbar_stream_set_cap(pjmedia_vid_dev_stream *strm, 120 121 pjmedia_vid_dev_cap cap, 121 122 const void *value); 122 static pj_status_t cbar_stream_get_frame(pjmedia_vid_ stream *strm,123 static pj_status_t cbar_stream_get_frame(pjmedia_vid_dev_stream *strm, 123 124 pjmedia_frame *frame); 124 static pj_status_t cbar_stream_start(pjmedia_vid_ stream *strm);125 static pj_status_t cbar_stream_stop(pjmedia_vid_ stream *strm);126 static pj_status_t cbar_stream_destroy(pjmedia_vid_ stream *strm);125 static pj_status_t cbar_stream_start(pjmedia_vid_dev_stream *strm); 126 static pj_status_t cbar_stream_stop(pjmedia_vid_dev_stream *strm); 127 static pj_status_t cbar_stream_destroy(pjmedia_vid_dev_stream *strm); 127 128 128 129 /* Operations */ … … 137 138 }; 138 139 139 static pjmedia_vid_ stream_op stream_op =140 static pjmedia_vid_dev_stream_op stream_op = 140 141 { 141 142 &cbar_stream_get_param, … … 355 356 356 357 /* API: create stream */ 357 static pj_status_t cbar_factory_create_stream(pjmedia_vid_dev_factory *f, 358 const pjmedia_vid_param *param, 359 const pjmedia_vid_cb *cb, 360 void *user_data, 361 pjmedia_vid_stream **p_vid_strm) 358 static pj_status_t cbar_factory_create_stream( 359 pjmedia_vid_dev_factory *f, 360 const pjmedia_vid_param *param, 361 const pjmedia_vid_cb *cb, 362 void *user_data, 363 pjmedia_vid_dev_stream **p_vid_strm) 362 364 { 363 365 struct cbar_factory *cf = (struct cbar_factory*)f; … … 420 422 421 423 /* API: Get stream info. */ 422 static pj_status_t cbar_stream_get_param(pjmedia_vid_ stream *s,424 static pj_status_t cbar_stream_get_param(pjmedia_vid_dev_stream *s, 423 425 pjmedia_vid_param *pi) 424 426 { … … 439 441 440 442 /* API: get capability */ 441 static pj_status_t cbar_stream_get_cap(pjmedia_vid_ stream *s,443 static pj_status_t cbar_stream_get_cap(pjmedia_vid_dev_stream *s, 442 444 pjmedia_vid_dev_cap cap, 443 445 void *pval) … … 459 461 460 462 /* API: set capability */ 461 static pj_status_t cbar_stream_set_cap(pjmedia_vid_ stream *s,463 static pj_status_t cbar_stream_set_cap(pjmedia_vid_dev_stream *s, 462 464 pjmedia_vid_dev_cap cap, 463 465 const void *pval) … … 553 555 554 556 /* API: Get frame from stream */ 555 static pj_status_t cbar_stream_get_frame(pjmedia_vid_ stream *strm,557 static pj_status_t cbar_stream_get_frame(pjmedia_vid_dev_stream *strm, 556 558 pjmedia_frame *frame) 557 559 { … … 562 564 563 565 /* API: Start stream. */ 564 static pj_status_t cbar_stream_start(pjmedia_vid_ stream *strm)566 static pj_status_t cbar_stream_start(pjmedia_vid_dev_stream *strm) 565 567 { 566 568 struct cbar_stream *stream = (struct cbar_stream*)strm; … … 574 576 575 577 /* API: Stop stream. */ 576 static pj_status_t cbar_stream_stop(pjmedia_vid_ stream *strm)578 static pj_status_t cbar_stream_stop(pjmedia_vid_dev_stream *strm) 577 579 { 578 580 struct cbar_stream *stream = (struct cbar_stream*)strm; … … 587 589 588 590 /* API: Destroy stream. */ 589 static pj_status_t cbar_stream_destroy(pjmedia_vid_ stream *strm)591 static pj_status_t cbar_stream_destroy(pjmedia_vid_dev_stream *strm) 590 592 { 591 593 struct cbar_stream *stream = (struct cbar_stream*)strm; -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshow_dev.c
r3402 r3420 90 90 struct dshow_stream 91 91 { 92 pjmedia_vid_ stream base; /**< Base stream*/93 pjmedia_vid_param param; /**< Settings*/94 pj_pool_t *pool; /**< Memory pool.*/95 96 pjmedia_vid_cb vid_cb; /**< Stream callback.*/97 void *user_data; /**< Application data.*/98 99 pj_bool_t 100 pj_bool_t rend_thread_exited;101 pj_bool_t cap_thread_exited;102 pj_bool_t cap_thread_initialized;103 pj_thread_desc cap_thread_desc;104 pj_thread_t *cap_thread;92 pjmedia_vid_dev_stream base; /**< Base stream */ 93 pjmedia_vid_param param; /**< Settings */ 94 pj_pool_t *pool; /**< Memory pool. */ 95 96 pjmedia_vid_cb vid_cb; /**< Stream callback. */ 97 void *user_data; /**< Application data. */ 98 99 pj_bool_t quit_flag; 100 pj_bool_t rend_thread_exited; 101 pj_bool_t cap_thread_exited; 102 pj_bool_t cap_thread_initialized; 103 pj_thread_desc cap_thread_desc; 104 pj_thread_t *cap_thread; 105 105 106 106 struct dshow_graph … … 127 127 unsigned index, 128 128 pjmedia_vid_param *param); 129 static pj_status_t dshow_factory_create_stream(pjmedia_vid_dev_factory *f, 130 const pjmedia_vid_param *param, 131 const pjmedia_vid_cb *cb, 132 void *user_data, 133 pjmedia_vid_stream **p_vid_strm); 134 135 static pj_status_t dshow_stream_get_param(pjmedia_vid_stream *strm, 129 static pj_status_t dshow_factory_create_stream( 130 pjmedia_vid_dev_factory *f, 131 const pjmedia_vid_param *param, 132 const pjmedia_vid_cb *cb, 133 void *user_data, 134 pjmedia_vid_dev_stream **p_vid_strm); 135 136 static pj_status_t dshow_stream_get_param(pjmedia_vid_dev_stream *strm, 136 137 pjmedia_vid_param *param); 137 static pj_status_t dshow_stream_get_cap(pjmedia_vid_ stream *strm,138 static pj_status_t dshow_stream_get_cap(pjmedia_vid_dev_stream *strm, 138 139 pjmedia_vid_dev_cap cap, 139 140 void *value); 140 static pj_status_t dshow_stream_set_cap(pjmedia_vid_ stream *strm,141 static pj_status_t dshow_stream_set_cap(pjmedia_vid_dev_stream *strm, 141 142 pjmedia_vid_dev_cap cap, 142 143 const void *value); 143 static pj_status_t dshow_stream_start(pjmedia_vid_ stream *strm);144 static pj_status_t dshow_stream_put_frame(pjmedia_vid_ stream *strm,144 static pj_status_t dshow_stream_start(pjmedia_vid_dev_stream *strm); 145 static pj_status_t dshow_stream_put_frame(pjmedia_vid_dev_stream *strm, 145 146 const pjmedia_frame *frame); 146 static pj_status_t dshow_stream_stop(pjmedia_vid_ stream *strm);147 static pj_status_t dshow_stream_destroy(pjmedia_vid_ stream *strm);147 static pj_status_t dshow_stream_stop(pjmedia_vid_dev_stream *strm); 148 static pj_status_t dshow_stream_destroy(pjmedia_vid_dev_stream *strm); 148 149 149 150 /* Operations */ … … 158 159 }; 159 160 160 static pjmedia_vid_ stream_op stream_op =161 static pjmedia_vid_dev_stream_op stream_op = 161 162 { 162 163 &dshow_stream_get_param, … … 396 397 /* Set the device capabilities here */ 397 398 param->clock_rate = DEFAULT_CLOCK_RATE; 398 param->frame_rate.num = DEFAULT_FPS;399 param->frame_rate.denum = 1;399 //param->frame_rate.num = DEFAULT_FPS; 400 //param->frame_rate.denum = 1; 400 401 param->flags = PJMEDIA_VID_DEV_CAP_FORMAT; 401 402 … … 439 440 440 441 /* API: Put frame from stream */ 441 static pj_status_t dshow_stream_put_frame(pjmedia_vid_ stream *strm,442 static pj_status_t dshow_stream_put_frame(pjmedia_vid_dev_stream *strm, 442 443 const pjmedia_frame *frame) 443 444 { … … 698 699 699 700 /* API: create stream */ 700 static pj_status_t dshow_factory_create_stream(pjmedia_vid_dev_factory *f, 701 const pjmedia_vid_param *param, 702 const pjmedia_vid_cb *cb, 703 void *user_data, 704 pjmedia_vid_stream **p_vid_strm) 701 static pj_status_t dshow_factory_create_stream( 702 pjmedia_vid_dev_factory *f, 703 const pjmedia_vid_param *param, 704 const pjmedia_vid_cb *cb, 705 void *user_data, 706 pjmedia_vid_dev_stream **p_vid_strm) 705 707 { 706 708 struct dshow_factory *df = (struct dshow_factory*)f; … … 753 755 754 756 on_error: 755 dshow_stream_destroy((pjmedia_vid_ stream *)strm);757 dshow_stream_destroy((pjmedia_vid_dev_stream *)strm); 756 758 return PJ_EUNKNOWN; 757 759 } 758 760 759 761 /* API: Get stream info. */ 760 static pj_status_t dshow_stream_get_param(pjmedia_vid_ stream *s,762 static pj_status_t dshow_stream_get_param(pjmedia_vid_dev_stream *s, 761 763 pjmedia_vid_param *pi) 762 764 { … … 777 779 778 780 /* API: get capability */ 779 static pj_status_t dshow_stream_get_cap(pjmedia_vid_ stream *s,781 static pj_status_t dshow_stream_get_cap(pjmedia_vid_dev_stream *s, 780 782 pjmedia_vid_dev_cap cap, 781 783 void *pval) … … 797 799 798 800 /* API: set capability */ 799 static pj_status_t dshow_stream_set_cap(pjmedia_vid_ stream *s,801 static pj_status_t dshow_stream_set_cap(pjmedia_vid_dev_stream *s, 800 802 pjmedia_vid_dev_cap cap, 801 803 const void *pval) … … 817 819 818 820 /* API: Start stream. */ 819 static pj_status_t dshow_stream_start(pjmedia_vid_ stream *strm)821 static pj_status_t dshow_stream_start(pjmedia_vid_dev_stream *strm) 820 822 { 821 823 struct dshow_stream *stream = (struct dshow_stream*)strm; … … 843 845 844 846 /* API: Stop stream. */ 845 static pj_status_t dshow_stream_stop(pjmedia_vid_ stream *strm)847 static pj_status_t dshow_stream_stop(pjmedia_vid_dev_stream *strm) 846 848 { 847 849 struct dshow_stream *stream = (struct dshow_stream*)strm; … … 869 871 870 872 /* API: Destroy stream. */ 871 static pj_status_t dshow_stream_destroy(pjmedia_vid_ stream *strm)873 static pj_status_t dshow_stream_destroy(pjmedia_vid_dev_stream *strm) 872 874 { 873 875 struct dshow_stream *stream = (struct dshow_stream*)strm; -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c
r3392 r3420 68 68 typedef struct ffmpeg_stream 69 69 { 70 pjmedia_vid_ streambase;70 pjmedia_vid_dev_stream base; 71 71 ffmpeg_factory *factory; 72 72 pj_pool_t *pool; … … 81 81 static unsigned ffmpeg_factory_get_dev_count(pjmedia_vid_dev_factory *f); 82 82 static pj_status_t ffmpeg_factory_get_dev_info(pjmedia_vid_dev_factory *f, 83 unsigned index,84 pjmedia_vid_dev_info *info);83 unsigned index, 84 pjmedia_vid_dev_info *info); 85 85 static pj_status_t ffmpeg_factory_default_param(pj_pool_t *pool, 86 86 pjmedia_vid_dev_factory *f, 87 87 unsigned index, 88 88 pjmedia_vid_param *param); 89 static pj_status_t ffmpeg_factory_create_stream(pjmedia_vid_dev_factory *f, 90 const pjmedia_vid_param *param, 91 const pjmedia_vid_cb *cb, 92 void *user_data, 93 pjmedia_vid_stream **p_vid_strm); 94 95 static pj_status_t ffmpeg_stream_get_param(pjmedia_vid_stream *strm, 96 pjmedia_vid_param *param); 97 static pj_status_t ffmpeg_stream_get_cap(pjmedia_vid_stream *strm, 98 pjmedia_vid_dev_cap cap, 99 void *value); 100 static pj_status_t ffmpeg_stream_set_cap(pjmedia_vid_stream *strm, 101 pjmedia_vid_dev_cap cap, 102 const void *value); 103 static pj_status_t ffmpeg_stream_start(pjmedia_vid_stream *strm); 104 static pj_status_t ffmpeg_stream_get_frame(pjmedia_vid_stream *s, 89 static pj_status_t ffmpeg_factory_create_stream( 90 pjmedia_vid_dev_factory *f, 91 const pjmedia_vid_param *param, 92 const pjmedia_vid_cb *cb, 93 void *user_data, 94 pjmedia_vid_dev_stream **p_vid_strm); 95 96 static pj_status_t ffmpeg_stream_get_param(pjmedia_vid_dev_stream *strm, 97 pjmedia_vid_param *param); 98 static pj_status_t ffmpeg_stream_get_cap(pjmedia_vid_dev_stream *strm, 99 pjmedia_vid_dev_cap cap, 100 void *value); 101 static pj_status_t ffmpeg_stream_set_cap(pjmedia_vid_dev_stream *strm, 102 pjmedia_vid_dev_cap cap, 103 const void *value); 104 static pj_status_t ffmpeg_stream_start(pjmedia_vid_dev_stream *strm); 105 static pj_status_t ffmpeg_stream_get_frame(pjmedia_vid_dev_stream *s, 105 106 pjmedia_frame *frame); 106 static pj_status_t ffmpeg_stream_stop(pjmedia_vid_ stream *strm);107 static pj_status_t ffmpeg_stream_destroy(pjmedia_vid_ stream *strm);107 static pj_status_t ffmpeg_stream_stop(pjmedia_vid_dev_stream *strm); 108 static pj_status_t ffmpeg_stream_destroy(pjmedia_vid_dev_stream *strm); 108 109 109 110 /* Operations */ … … 118 119 }; 119 120 120 static pjmedia_vid_ stream_op stream_op =121 static pjmedia_vid_dev_stream_op stream_op = 121 122 { 122 123 &ffmpeg_stream_get_param, … … 153 154 { 154 155 AVFormatParameters fp; 155 pjmedia_video_format_detail * fmt_detail;156 pjmedia_video_format_detail *vfd; 156 157 int err; 157 158 … … 160 161 PJ_EINVAL); 161 162 162 fmt_detail = (pjmedia_video_format_detail*)param->fmt.detail;163 vfd = pjmedia_format_get_video_format_detail(¶m->fmt, PJ_TRUE); 163 164 164 165 /* Init ffmpeg format context */ … … 168 169 pj_bzero(&fp, sizeof(fp)); 169 170 fp.prealloced_context = 1; 170 fp.width = fmt_detail->size.w;171 fp.height = fmt_detail->size.h;171 fp.width = vfd->size.w; 172 fp.height = vfd->size.h; 172 173 fp.pix_fmt = PIX_FMT_BGR24; 173 fp.time_base.num = param->frame_rate.denum;174 fp.time_base.den = param->frame_rate.num;174 fp.time_base.num = vfd->fps.denum; 175 fp.time_base.den = vfd->fps.num; 175 176 176 177 /* Open capture stream */ … … 289 290 /* API: get device info */ 290 291 static pj_status_t ffmpeg_factory_get_dev_info(pjmedia_vid_dev_factory *f, 291 unsigned index,292 pjmedia_vid_dev_info *info)292 unsigned index, 293 pjmedia_vid_dev_info *info) 293 294 { 294 295 ffmpeg_factory *ff = (ffmpeg_factory*)f; … … 309 310 ffmpeg_factory *ff = (ffmpeg_factory*)f; 310 311 ffmpeg_dev_info *info; 311 pjmedia_video_format_detail *fmt_detail;312 312 313 313 PJ_ASSERT_RETURN(index < ff->dev_count, PJMEDIA_EVID_INVDEV); 314 315 PJ_UNUSED_ARG(pool); 316 314 317 info = &ff->dev_info[index]; 315 318 … … 322 325 /* Set the device capabilities here */ 323 326 param->flags = PJMEDIA_VID_DEV_CAP_FORMAT; 324 pj_memcpy(¶m->fmt, &info->base.fmt[0], sizeof(param->fmt));325 327 param->clock_rate = 90000; 326 pjmedia_format_init_video(pool, ¶m->fmt, 320, 240, 25, 1, 327 0, 0); 328 fmt_detail = (pjmedia_video_format_detail*)param->fmt.detail; 329 param->frame_rate.num = fmt_detail->fps.num; 330 param->frame_rate.denum = fmt_detail->fps.denum; 328 pjmedia_format_init_video(¶m->fmt, 0, 320, 240, 25, 1); 329 param->fmt.id = info->base.fmt[0].id; 331 330 332 331 return PJ_SUCCESS; … … 336 335 337 336 /* API: create stream */ 338 static pj_status_t ffmpeg_factory_create_stream(pjmedia_vid_dev_factory *f, 339 const pjmedia_vid_param *param, 340 const pjmedia_vid_cb *cb, 341 void *user_data, 342 pjmedia_vid_stream **p_vid_strm) 337 static pj_status_t ffmpeg_factory_create_stream( 338 pjmedia_vid_dev_factory *f, 339 const pjmedia_vid_param *param, 340 const pjmedia_vid_cb *cb, 341 void *user_data, 342 pjmedia_vid_dev_stream **p_vid_strm) 343 343 { 344 344 ffmpeg_factory *ff = (ffmpeg_factory*)f; … … 349 349 PJ_ASSERT_RETURN(param->dir == PJMEDIA_DIR_CAPTURE, PJ_EINVAL); 350 350 PJ_ASSERT_RETURN((unsigned)param->cap_id < ff->dev_count, PJ_EINVAL); 351 PJ_ASSERT_RETURN(param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&352 param->fmt.detail,PJ_EINVAL);351 PJ_ASSERT_RETURN(param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO, 352 PJ_EINVAL); 353 353 354 354 PJ_UNUSED_ARG(cb); … … 372 372 373 373 /* API: Get stream info. */ 374 static pj_status_t ffmpeg_stream_get_param(pjmedia_vid_ stream *s,374 static pj_status_t ffmpeg_stream_get_param(pjmedia_vid_dev_stream *s, 375 375 pjmedia_vid_param *pi) 376 376 { … … 385 385 386 386 /* API: get capability */ 387 static pj_status_t ffmpeg_stream_get_cap(pjmedia_vid_ stream *s,388 pjmedia_vid_dev_cap cap,389 void *pval)387 static pj_status_t ffmpeg_stream_get_cap(pjmedia_vid_dev_stream *s, 388 pjmedia_vid_dev_cap cap, 389 void *pval) 390 390 { 391 391 ffmpeg_stream *strm = (ffmpeg_stream*)s; … … 399 399 400 400 /* API: set capability */ 401 static pj_status_t ffmpeg_stream_set_cap(pjmedia_vid_ stream *s,402 pjmedia_vid_dev_cap cap,403 const void *pval)401 static pj_status_t ffmpeg_stream_set_cap(pjmedia_vid_dev_stream *s, 402 pjmedia_vid_dev_cap cap, 403 const void *pval) 404 404 { 405 405 ffmpeg_stream *strm = (ffmpeg_stream*)s; … … 414 414 415 415 /* API: Start stream. */ 416 static pj_status_t ffmpeg_stream_start(pjmedia_vid_ stream *s)416 static pj_status_t ffmpeg_stream_start(pjmedia_vid_dev_stream *s) 417 417 { 418 418 ffmpeg_stream *strm = (ffmpeg_stream*)s; … … 436 436 437 437 /* API: Get frame from stream */ 438 static pj_status_t ffmpeg_stream_get_frame(pjmedia_vid_ stream *s,438 static pj_status_t ffmpeg_stream_get_frame(pjmedia_vid_dev_stream *s, 439 439 pjmedia_frame *frame) 440 440 { … … 459 459 460 460 /* API: Stop stream. */ 461 static pj_status_t ffmpeg_stream_stop(pjmedia_vid_ stream *s)461 static pj_status_t ffmpeg_stream_stop(pjmedia_vid_dev_stream *s) 462 462 { 463 463 ffmpeg_stream *strm = (ffmpeg_stream*)s; … … 473 473 474 474 /* API: Destroy stream. */ 475 static pj_status_t ffmpeg_stream_destroy(pjmedia_vid_ stream *s)475 static pj_status_t ffmpeg_stream_destroy(pjmedia_vid_dev_stream *s) 476 476 { 477 477 ffmpeg_stream *strm = (ffmpeg_stream*)s; -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c
r3401 r3420 91 91 struct sdl_stream 92 92 { 93 pjmedia_vid_ stream base; /**< Base stream*/94 pjmedia_vid_param param; /**< Settings*/95 pj_pool_t *pool; /**< Memory pool.*/96 97 pjmedia_vid_cb vid_cb; /**< Stream callback.*/98 void *user_data; /**< Application data.*/99 100 pj_thread_t *sdl_thread; /**< SDL thread.*/101 pj_bool_t 102 pj_bool_t 103 pj_bool_t 104 pj_status_t 105 106 SDL_Rect rect; /**< Display rectangle.*/107 SDL_Surface *screen; /**< Display screen.*/108 SDL_Surface *surf; /**< RGB surface.*/109 SDL_Overlay *overlay; /**< YUV overlay.*/93 pjmedia_vid_dev_stream base; /**< Base stream */ 94 pjmedia_vid_param param; /**< Settings */ 95 pj_pool_t *pool; /**< Memory pool. */ 96 97 pjmedia_vid_cb vid_cb; /**< Stream callback. */ 98 void *user_data; /**< Application data. */ 99 100 pj_thread_t *sdl_thread; /**< SDL thread. */ 101 pj_bool_t is_quitting; 102 pj_bool_t is_running; 103 pj_bool_t render_exited; 104 pj_status_t status; 105 106 SDL_Rect rect; /**< Display rectangle. */ 107 SDL_Surface *screen; /**< Display screen. */ 108 SDL_Surface *surf; /**< RGB surface. */ 109 SDL_Overlay *overlay; /**< YUV overlay. */ 110 110 111 111 /* For frame conversion */ 112 pjmedia_converter 113 pjmedia_conversion_param conv_param;114 pjmedia_frame 112 pjmedia_converter *conv; 113 pjmedia_conversion_param conv_param; 114 pjmedia_frame conv_buf; 115 115 116 116 pjmedia_video_apply_fmt_param vafp; … … 129 129 unsigned index, 130 130 pjmedia_vid_param *param); 131 static pj_status_t sdl_factory_create_stream(pjmedia_vid_dev_factory *f, 132 const pjmedia_vid_param *param, 133 const pjmedia_vid_cb *cb, 134 void *user_data, 135 pjmedia_vid_stream **p_vid_strm); 136 137 static pj_status_t sdl_stream_get_param(pjmedia_vid_stream *strm, 131 static pj_status_t sdl_factory_create_stream( 132 pjmedia_vid_dev_factory *f, 133 const pjmedia_vid_param *param, 134 const pjmedia_vid_cb *cb, 135 void *user_data, 136 pjmedia_vid_dev_stream **p_vid_strm); 137 138 static pj_status_t sdl_stream_get_param(pjmedia_vid_dev_stream *strm, 138 139 pjmedia_vid_param *param); 139 static pj_status_t sdl_stream_get_cap(pjmedia_vid_ stream *strm,140 static pj_status_t sdl_stream_get_cap(pjmedia_vid_dev_stream *strm, 140 141 pjmedia_vid_dev_cap cap, 141 142 void *value); 142 static pj_status_t sdl_stream_set_cap(pjmedia_vid_ stream *strm,143 static pj_status_t sdl_stream_set_cap(pjmedia_vid_dev_stream *strm, 143 144 pjmedia_vid_dev_cap cap, 144 145 const void *value); 145 static pj_status_t sdl_stream_put_frame(pjmedia_vid_ stream *strm,146 static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm, 146 147 const pjmedia_frame *frame); 147 static pj_status_t sdl_stream_start(pjmedia_vid_ stream *strm);148 static pj_status_t sdl_stream_stop(pjmedia_vid_ stream *strm);149 static pj_status_t sdl_stream_destroy(pjmedia_vid_ stream *strm);148 static pj_status_t sdl_stream_start(pjmedia_vid_dev_stream *strm); 149 static pj_status_t sdl_stream_stop(pjmedia_vid_dev_stream *strm); 150 static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm); 150 151 151 152 /* Operations */ … … 160 161 }; 161 162 162 static pjmedia_vid_ stream_op stream_op =163 static pjmedia_vid_dev_stream_op stream_op = 163 164 { 164 165 &sdl_stream_get_param, … … 408 409 } 409 410 if (strm->is_running) 410 pjmedia_vid_ stream_stop(&strm->base);411 pjmedia_vid_dev_stream_stop(&strm->base); 411 412 else 412 pjmedia_vid_ stream_start(&strm->base);413 pjmedia_vid_dev_stream_start(&strm->base); 413 414 break; 414 415 case SDL_VIDEORESIZE: … … 434 435 * To process PJMEDIA_EVENT_WINDOW_CLOSE event, 435 436 * application should do this in the on_event_cb callback: 436 * 1. stop further calls to #pjmedia_vid_stream_put_frame() 437 * 1. stop further calls to 438 * #pjmedia_vid_dev_stream_put_frame() 437 439 * 2. return PJ_SUCCESS 438 440 * Upon returning from the callback, SDL will destroy its … … 484 486 485 487 /* API: create stream */ 486 static pj_status_t sdl_factory_create_stream(pjmedia_vid_dev_factory *f, 487 const pjmedia_vid_param *param, 488 const pjmedia_vid_cb *cb, 489 void *user_data, 490 pjmedia_vid_stream **p_vid_strm) 488 static pj_status_t sdl_factory_create_stream( 489 pjmedia_vid_dev_factory *f, 490 const pjmedia_vid_param *param, 491 const pjmedia_vid_cb *cb, 492 void *user_data, 493 pjmedia_vid_dev_stream **p_vid_strm) 491 494 { 492 495 struct sdl_factory *sf = (struct sdl_factory*)f; … … 549 552 550 553 /* API: Get stream info. */ 551 static pj_status_t sdl_stream_get_param(pjmedia_vid_ stream *s,554 static pj_status_t sdl_stream_get_param(pjmedia_vid_dev_stream *s, 552 555 pjmedia_vid_param *pi) 553 556 { … … 568 571 569 572 /* API: get capability */ 570 static pj_status_t sdl_stream_get_cap(pjmedia_vid_ stream *s,573 static pj_status_t sdl_stream_get_cap(pjmedia_vid_dev_stream *s, 571 574 pjmedia_vid_dev_cap cap, 572 575 void *pval) … … 587 590 588 591 /* API: set capability */ 589 static pj_status_t sdl_stream_set_cap(pjmedia_vid_ stream *s,592 static pj_status_t sdl_stream_set_cap(pjmedia_vid_dev_stream *s, 590 593 pjmedia_vid_dev_cap cap, 591 594 const void *pval) … … 606 609 607 610 /* API: Put frame from stream */ 608 static pj_status_t sdl_stream_put_frame(pjmedia_vid_ stream *strm,611 static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm, 609 612 const pjmedia_frame *frame) 610 613 { … … 665 668 666 669 /* API: Start stream. */ 667 static pj_status_t sdl_stream_start(pjmedia_vid_ stream *strm)670 static pj_status_t sdl_stream_start(pjmedia_vid_dev_stream *strm) 668 671 { 669 672 struct sdl_stream *stream = (struct sdl_stream*)strm; … … 678 681 679 682 /* API: Stop stream. */ 680 static pj_status_t sdl_stream_stop(pjmedia_vid_ stream *strm)683 static pj_status_t sdl_stream_stop(pjmedia_vid_dev_stream *strm) 681 684 { 682 685 struct sdl_stream *stream = (struct sdl_stream*)strm; … … 695 698 696 699 /* API: Destroy stream. */ 697 static pj_status_t sdl_stream_destroy(pjmedia_vid_ stream *strm)700 static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm) 698 701 { 699 702 struct sdl_stream *stream = (struct sdl_stream*)strm; -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/videodev.c
r3395 r3420 425 425 unsigned i; 426 426 427 /* Allow shutdown() to be called multiple times as long as there is matching428 * number of init().427 /* Allow shutdown() to be called multiple times as long as there is 428 * matching number of init(). 429 429 */ 430 430 if (vid_subsys.init_count == 0) { … … 547 547 548 548 for (drv_idx=0; drv_idx<vid_subsys.drv_cnt; ++drv_idx) { 549 if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name)) { 549 if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name)) 550 { 550 551 f = vid_subsys.drv[drv_idx].f; 551 552 break; … … 556 557 return PJ_ENOTFOUND; 557 558 558 for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx) { 559 for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx) 560 { 559 561 pjmedia_vid_dev_info info; 560 562 pj_status_t status; … … 607 609 608 610 /* API: Open video stream object using the specified parameters. */ 609 PJ_DEF(pj_status_t) pjmedia_vid_stream_create(const pjmedia_vid_param *prm, 610 const pjmedia_vid_cb *cb, 611 void *user_data, 612 pjmedia_vid_stream **p_vid_strm) 611 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_create( 612 const pjmedia_vid_param *prm, 613 const pjmedia_vid_cb *cb, 614 void *user_data, 615 pjmedia_vid_dev_stream **p_vid_strm) 613 616 { 614 617 pjmedia_vid_dev_factory *cap_f=NULL, *rend_f=NULL, *f=NULL; … … 675 678 676 679 /* API: Get the running parameters for the specified video stream. */ 677 PJ_DEF(pj_status_t) pjmedia_vid_stream_get_param(pjmedia_vid_stream *strm, 678 pjmedia_vid_param *param) 680 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_param( 681 pjmedia_vid_dev_stream *strm, 682 pjmedia_vid_param *param) 679 683 { 680 684 pj_status_t status; … … 695 699 696 700 /* API: Get the value of a specific capability of the video stream. */ 697 PJ_DEF(pj_status_t) pjmedia_vid_stream_get_cap(pjmedia_vid_stream *strm, 698 pjmedia_vid_dev_cap cap, 699 void *value) 701 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_cap( 702 pjmedia_vid_dev_stream *strm, 703 pjmedia_vid_dev_cap cap, 704 void *value) 700 705 { 701 706 return strm->op->get_cap(strm, cap, value); … … 703 708 704 709 /* API: Set the value of a specific capability of the video stream. */ 705 PJ_DEF(pj_status_t) pjmedia_vid_stream_set_cap(pjmedia_vid_stream *strm, 706 pjmedia_vid_dev_cap cap, 707 const void *value) 710 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_set_cap( 711 pjmedia_vid_dev_stream *strm, 712 pjmedia_vid_dev_cap cap, 713 const void *value) 708 714 { 709 715 return strm->op->set_cap(strm, cap, value); … … 711 717 712 718 /* API: Start the stream. */ 713 PJ_DEF(pj_status_t) pjmedia_vid_ stream_start(pjmedia_vid_stream *strm)719 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm) 714 720 { 715 721 return strm->op->start(strm); 716 722 } 717 723 718 PJ_DEF(pj_status_t) pjmedia_vid_stream_get_frame(pjmedia_vid_stream *strm, 719 pjmedia_frame *frame) 724 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_frame( 725 pjmedia_vid_dev_stream *strm, 726 pjmedia_frame *frame) 720 727 { 721 728 pj_assert(strm->op->get_frame); … … 723 730 } 724 731 725 PJ_DEF(pj_status_t) pjmedia_vid_stream_put_frame(pjmedia_vid_stream *strm, 726 const pjmedia_frame *frame) 732 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_put_frame( 733 pjmedia_vid_dev_stream *strm, 734 const pjmedia_frame *frame) 727 735 { 728 736 pj_assert(strm->op->put_frame); … … 731 739 732 740 /* API: Stop the stream. */ 733 PJ_DEF(pj_status_t) pjmedia_vid_ stream_stop(pjmedia_vid_stream *strm)741 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_stop(pjmedia_vid_dev_stream *strm) 734 742 { 735 743 return strm->op->stop(strm); … … 737 745 738 746 /* API: Destroy the stream. */ 739 PJ_DEF(pj_status_t) pjmedia_vid_stream_destroy(pjmedia_vid_stream *strm) 747 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_destroy( 748 pjmedia_vid_dev_stream *strm) 740 749 { 741 750 return strm->op->destroy(strm); -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/jbuf.c
r3359 r3420 69 69 pj_size_t *content_len; /**< frame length array */ 70 70 pj_uint32_t *bit_info; /**< frame bit info array */ 71 pj_uint32_t *ts; /**< timestamp array */ 71 72 72 73 /* States */ … … 198 199 sizeof(framelist->bit_info[0])* 199 200 framelist->max_count); 200 201 framelist->ts = (pj_uint32_t*) 202 pj_pool_alloc(pool, 203 sizeof(framelist->ts[0])* 204 framelist->max_count); 201 205 202 206 return jb_framelist_reset(framelist); … … 259 263 void *frame, pj_size_t *size, 260 264 pjmedia_jb_frame_type *p_type, 261 pj_uint32_t *bit_info) 265 pj_uint32_t *bit_info, 266 pj_uint32_t *ts) 262 267 { 263 268 if (framelist->size) { … … 282 287 if (bit_info) 283 288 *bit_info = framelist->bit_info[framelist->head]; 289 if (ts) 290 *ts = framelist->ts[framelist->head]; 284 291 285 292 //pj_bzero(framelist->content + … … 289 296 framelist->content_len[framelist->head] = 0; 290 297 framelist->bit_info[framelist->head] = 0; 298 framelist->ts[framelist->head] = 0; 291 299 292 300 framelist->origin++; … … 302 310 303 311 return PJ_FALSE; 312 } 313 314 315 static pj_bool_t jb_framelist_peek(jb_framelist_t *framelist, 316 unsigned idx, 317 const void **frame, 318 pj_size_t *size, 319 pjmedia_jb_frame_type *type, 320 pj_uint32_t *bit_info, 321 pj_uint32_t *ts) 322 { 323 unsigned pos; 324 325 if (idx >= jb_framelist_eff_size(framelist)) 326 return PJ_FALSE; 327 328 pos = framelist->head; 329 330 /* Find actual peek position, note there may be discarded frames */ 331 while (1) { 332 if (framelist->frame_type[pos] != PJMEDIA_JB_DISCARDED_FRAME) { 333 if (idx == 0) 334 break; 335 else 336 --idx; 337 } 338 pos = (pos + 1) % framelist->max_count; 339 } 340 341 /* Return the frame pointer */ 342 if (frame) 343 *frame = framelist->content + pos*framelist->frame_size; 344 if (type) 345 *type = (pjmedia_jb_frame_type) 346 framelist->frame_type[pos]; 347 if (size) 348 *size = framelist->content_len[pos]; 349 if (bit_info) 350 *bit_info = framelist->bit_info[pos]; 351 if (ts) 352 *ts = framelist->ts[pos]; 353 354 return PJ_TRUE; 304 355 } 305 356 … … 373 424 unsigned frame_size, 374 425 pj_uint32_t bit_info, 426 pj_uint32_t ts, 375 427 unsigned frame_type) 376 428 { … … 426 478 framelist->content_len[pos] = frame_size; 427 479 framelist->bit_info[pos] = bit_info; 480 framelist->ts[pos] = ts; 428 481 429 482 /* update framelist size */ … … 735 788 int frame_seq) 736 789 { 737 pjmedia_jbuf_put_frame 2(jb, frame, frame_size, 0, frame_seq, NULL);790 pjmedia_jbuf_put_frame3(jb, frame, frame_size, 0, frame_seq, 0, NULL); 738 791 } 739 792 … … 743 796 pj_uint32_t bit_info, 744 797 int frame_seq, 798 pj_bool_t *discarded) 799 { 800 pjmedia_jbuf_put_frame3(jb, frame, frame_size, bit_info, frame_seq, 0, 801 discarded); 802 } 803 804 PJ_DEF(void) pjmedia_jbuf_put_frame3(pjmedia_jbuf *jb, 805 const void *frame, 806 pj_size_t frame_size, 807 pj_uint32_t bit_info, 808 int frame_seq, 809 pj_uint32_t ts, 745 810 pj_bool_t *discarded) 746 811 { … … 812 877 min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size); 813 878 status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 814 min_frame_size, bit_info, frame_type);879 min_frame_size, bit_info, ts, frame_type); 815 880 816 881 /* Jitter buffer is full, remove some older frames */ … … 835 900 removed = jb_framelist_remove_head(&jb->jb_framelist, distance); 836 901 status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 837 min_frame_size, bit_info, frame_type);902 min_frame_size, bit_info, ts, frame_type); 838 903 839 904 jb->jb_discard += removed; … … 867 932 char *p_frame_type) 868 933 { 869 pjmedia_jbuf_get_frame 2(jb, frame, NULL, p_frame_type, NULL);934 pjmedia_jbuf_get_frame3(jb, frame, NULL, p_frame_type, NULL, NULL); 870 935 } 871 936 … … 879 944 pj_uint32_t *bit_info) 880 945 { 946 pjmedia_jbuf_get_frame3(jb, frame, size, p_frame_type, bit_info, NULL); 947 } 948 949 /* 950 * Get frame from jitter buffer. 951 */ 952 PJ_DEF(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb, 953 void *frame, 954 pj_size_t *size, 955 char *p_frame_type, 956 pj_uint32_t *bit_info, 957 pj_uint32_t *ts) 958 { 881 959 if (jb->jb_status == JB_STATUS_PREFETCHING) { 882 960 … … 902 980 /* Try to retrieve a frame from frame list */ 903 981 res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype, 904 bit_info );982 bit_info, ts); 905 983 if (res) { 906 984 /* We've successfully retrieved a frame from the frame list, but … … 970 1048 } 971 1049 1050 1051 PJ_DEF(void) pjmedia_jbuf_peek_frame( pjmedia_jbuf *jb, 1052 unsigned idx, 1053 const void **frame, 1054 pj_size_t *size, 1055 char *p_frm_type, 1056 pj_uint32_t *bit_info, 1057 pj_uint32_t *ts) 1058 { 1059 pjmedia_jb_frame_type ftype; 1060 pj_bool_t res; 1061 1062 res = jb_framelist_peek(&jb->jb_framelist, idx, frame, size, &ftype, bit_info, ts); 1063 if (!res) 1064 *p_frm_type = PJMEDIA_JB_ZERO_EMPTY_FRAME; 1065 else if (ftype == PJMEDIA_JB_NORMAL_FRAME) 1066 *p_frm_type = PJMEDIA_JB_NORMAL_FRAME; 1067 else 1068 *p_frm_type = PJMEDIA_JB_MISSING_FRAME; 1069 } 1070 1071 1072 PJ_DEF(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb, 1073 unsigned frame_cnt) 1074 { 1075 unsigned count, last_discard_num; 1076 1077 last_discard_num = jb->jb_framelist.discarded_num; 1078 count = jb_framelist_remove_head(&jb->jb_framelist, frame_cnt); 1079 1080 /* Remove some more when there were discarded frames included */ 1081 while (jb->jb_framelist.discarded_num < last_discard_num) { 1082 /* Calculate frames count to be removed next */ 1083 frame_cnt = last_discard_num - jb->jb_framelist.discarded_num; 1084 1085 /* Normalize non-discarded frames count just been removed */ 1086 count -= frame_cnt; 1087 1088 /* Remove more frames */ 1089 last_discard_num = jb->jb_framelist.discarded_num; 1090 count += jb_framelist_remove_head(&jb->jb_framelist, frame_cnt); 1091 } 1092 1093 return count; 1094 } -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/stream.c
r3418 r3420 23 23 #include <pjmedia/rtcp.h> 24 24 #include <pjmedia/jbuf.h> 25 #include <pjmedia/stream_common.h> 25 26 #include <pj/array.h> 26 27 #include <pj/assert.h> … … 2739 2740 } 2740 2741 2742 2743 static const pj_str_t ID_AUDIO = { "audio", 5}; 2744 static const pj_str_t ID_VIDEO = { "video", 5}; 2745 static const pj_str_t ID_APPLICATION = { "application", 11}; 2746 static const pj_str_t ID_IN = { "IN", 2 }; 2747 static const pj_str_t ID_IP4 = { "IP4", 3}; 2748 static const pj_str_t ID_IP6 = { "IP6", 3}; 2749 static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 }; 2750 static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 }; 2751 //static const pj_str_t ID_SDP_NAME = { "pjmedia", 7 }; 2752 static const pj_str_t ID_RTPMAP = { "rtpmap", 6 }; 2753 static const pj_str_t ID_TELEPHONE_EVENT = { "telephone-event", 15 }; 2754 2755 static const pj_str_t STR_INACTIVE = { "inactive", 8 }; 2756 static const pj_str_t STR_SENDRECV = { "sendrecv", 8 }; 2757 static const pj_str_t STR_SENDONLY = { "sendonly", 8 }; 2758 static const pj_str_t STR_RECVONLY = { "recvonly", 8 }; 2759 2760 2761 /* 2762 * Internal function for collecting codec info and param from the SDP media. 2763 */ 2764 static pj_status_t get_audio_codec_info_param(pjmedia_stream_info *si, 2765 pj_pool_t *pool, 2766 pjmedia_codec_mgr *mgr, 2767 const pjmedia_sdp_media *local_m, 2768 const pjmedia_sdp_media *rem_m) 2769 { 2770 const pjmedia_sdp_attr *attr; 2771 pjmedia_sdp_rtpmap *rtpmap; 2772 unsigned i, fmti, pt = 0; 2773 pj_status_t status; 2774 2775 /* Find the first codec which is not telephone-event */ 2776 for ( fmti = 0; fmti < local_m->desc.fmt_count; ++fmti ) { 2777 if ( !pj_isdigit(*local_m->desc.fmt[fmti].ptr) ) 2778 return PJMEDIA_EINVALIDPT; 2779 pt = pj_strtoul(&local_m->desc.fmt[fmti]); 2780 if ( PJMEDIA_RTP_PT_TELEPHONE_EVENTS == 0 || 2781 pt != PJMEDIA_RTP_PT_TELEPHONE_EVENTS ) 2782 break; 2783 } 2784 if ( fmti >= local_m->desc.fmt_count ) 2785 return PJMEDIA_EINVALIDPT; 2786 2787 /* Get codec info. 2788 * For static payload types, get the info from codec manager. 2789 * For dynamic payload types, MUST get the rtpmap. 2790 */ 2791 if (pt < 96) { 2792 pj_bool_t has_rtpmap; 2793 2794 rtpmap = NULL; 2795 has_rtpmap = PJ_TRUE; 2796 2797 attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP, 2798 &local_m->desc.fmt[fmti]); 2799 if (attr == NULL) { 2800 has_rtpmap = PJ_FALSE; 2801 } 2802 if (attr != NULL) { 2803 status = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap); 2804 if (status != PJ_SUCCESS) 2805 has_rtpmap = PJ_FALSE; 2806 } 2807 2808 /* Build codec format info: */ 2809 if (has_rtpmap) { 2810 si->fmt.type = si->type; 2811 si->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]); 2812 pj_strdup(pool, &si->fmt.encoding_name, &rtpmap->enc_name); 2813 si->fmt.clock_rate = rtpmap->clock_rate; 2814 2815 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG != 0) 2816 /* The session info should have the actual clock rate, because 2817 * this info is used for calculationg buffer size, etc in stream 2818 */ 2819 if (si->fmt.pt == PJMEDIA_RTP_PT_G722) 2820 si->fmt.clock_rate = 16000; 2821 #endif 2822 2823 /* For audio codecs, rtpmap parameters denotes the number of 2824 * channels. 2825 */ 2826 if (si->type == PJMEDIA_TYPE_AUDIO && rtpmap->param.slen) { 2827 si->fmt.channel_cnt = (unsigned) pj_strtoul(&rtpmap->param); 2828 } else { 2829 si->fmt.channel_cnt = 1; 2830 } 2831 2832 } else { 2833 const pjmedia_codec_info *p_info; 2834 2835 status = pjmedia_codec_mgr_get_codec_info( mgr, pt, &p_info); 2836 if (status != PJ_SUCCESS) 2837 return status; 2838 2839 pj_memcpy(&si->fmt, p_info, sizeof(pjmedia_codec_info)); 2840 } 2841 2842 /* For static payload type, pt's are symetric */ 2843 si->tx_pt = pt; 2844 2845 } else { 2846 2847 attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP, 2848 &local_m->desc.fmt[fmti]); 2849 if (attr == NULL) 2850 return PJMEDIA_EMISSINGRTPMAP; 2851 2852 status = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap); 2853 if (status != PJ_SUCCESS) 2854 return status; 2855 2856 /* Build codec format info: */ 2857 2858 si->fmt.type = si->type; 2859 si->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]); 2860 pj_strdup(pool, &si->fmt.encoding_name, &rtpmap->enc_name); 2861 si->fmt.clock_rate = rtpmap->clock_rate; 2862 2863 /* For audio codecs, rtpmap parameters denotes the number of 2864 * channels. 2865 */ 2866 if (si->type == PJMEDIA_TYPE_AUDIO && rtpmap->param.slen) { 2867 si->fmt.channel_cnt = (unsigned) pj_strtoul(&rtpmap->param); 2868 } else { 2869 si->fmt.channel_cnt = 1; 2870 } 2871 2872 /* Determine payload type for outgoing channel, by finding 2873 * dynamic payload type in remote SDP that matches the answer. 2874 */ 2875 si->tx_pt = 0xFFFF; 2876 for (i=0; i<rem_m->desc.fmt_count; ++i) { 2877 unsigned rpt; 2878 pjmedia_sdp_attr *r_attr; 2879 pjmedia_sdp_rtpmap r_rtpmap; 2880 2881 rpt = pj_strtoul(&rem_m->desc.fmt[i]); 2882 if (rpt < 96) 2883 continue; 2884 2885 r_attr = pjmedia_sdp_media_find_attr(rem_m, &ID_RTPMAP, 2886 &rem_m->desc.fmt[i]); 2887 if (!r_attr) 2888 continue; 2889 2890 if (pjmedia_sdp_attr_get_rtpmap(r_attr, &r_rtpmap) != PJ_SUCCESS) 2891 continue; 2892 2893 if (!pj_stricmp(&rtpmap->enc_name, &r_rtpmap.enc_name) && 2894 rtpmap->clock_rate == r_rtpmap.clock_rate) 2895 { 2896 /* Found matched codec. */ 2897 si->tx_pt = rpt; 2898 2899 break; 2900 } 2901 } 2902 2903 if (si->tx_pt == 0xFFFF) 2904 return PJMEDIA_EMISSINGRTPMAP; 2905 } 2906 2907 2908 /* Now that we have codec info, get the codec param. */ 2909 si->param = PJ_POOL_ALLOC_T(pool, pjmedia_codec_param); 2910 status = pjmedia_codec_mgr_get_default_param(mgr, &si->fmt, 2911 si->param); 2912 2913 /* Get remote fmtp for our encoder. */ 2914 pjmedia_stream_info_parse_fmtp(pool, rem_m, si->tx_pt, 2915 &si->param->setting.enc_fmtp); 2916 2917 /* Get local fmtp for our decoder. */ 2918 pjmedia_stream_info_parse_fmtp(pool, local_m, si->fmt.pt, 2919 &si->param->setting.dec_fmtp); 2920 2921 /* Get the remote ptime for our encoder. */ 2922 attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 2923 "ptime", NULL); 2924 if (attr) { 2925 pj_str_t tmp_val = attr->value; 2926 unsigned frm_per_pkt; 2927 2928 pj_strltrim(&tmp_val); 2929 2930 /* Round up ptime when the specified is not multiple of frm_ptime */ 2931 frm_per_pkt = (pj_strtoul(&tmp_val) + 2932 si->param->info.frm_ptime/2) / 2933 si->param->info.frm_ptime; 2934 if (frm_per_pkt != 0) { 2935 si->param->setting.frm_per_pkt = (pj_uint8_t)frm_per_pkt; 2936 } 2937 } 2938 2939 /* Get remote maxptime for our encoder. */ 2940 attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 2941 "maxptime", NULL); 2942 if (attr) { 2943 pj_str_t tmp_val = attr->value; 2944 2945 pj_strltrim(&tmp_val); 2946 si->tx_maxptime = pj_strtoul(&tmp_val); 2947 } 2948 2949 /* When direction is NONE (it means SDP negotiation has failed) we don't 2950 * need to return a failure here, as returning failure will cause 2951 * the whole SDP to be rejected. See ticket #: 2952 * http:// 2953 * 2954 * Thanks Alain Totouom 2955 */ 2956 if (status != PJ_SUCCESS && si->dir != PJMEDIA_DIR_NONE) 2957 return status; 2958 2959 2960 /* Get incomming payload type for telephone-events */ 2961 si->rx_event_pt = -1; 2962 for (i=0; i<local_m->attr_count; ++i) { 2963 pjmedia_sdp_rtpmap r; 2964 2965 attr = local_m->attr[i]; 2966 if (pj_strcmp(&attr->name, &ID_RTPMAP) != 0) 2967 continue; 2968 if (pjmedia_sdp_attr_get_rtpmap(attr, &r) != PJ_SUCCESS) 2969 continue; 2970 if (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) == 0) { 2971 si->rx_event_pt = pj_strtoul(&r.pt); 2972 break; 2973 } 2974 } 2975 2976 /* Get outgoing payload type for telephone-events */ 2977 si->tx_event_pt = -1; 2978 for (i=0; i<rem_m->attr_count; ++i) { 2979 pjmedia_sdp_rtpmap r; 2980 2981 attr = rem_m->attr[i]; 2982 if (pj_strcmp(&attr->name, &ID_RTPMAP) != 0) 2983 continue; 2984 if (pjmedia_sdp_attr_get_rtpmap(attr, &r) != PJ_SUCCESS) 2985 continue; 2986 if (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) == 0) { 2987 si->tx_event_pt = pj_strtoul(&r.pt); 2988 break; 2989 } 2990 } 2991 2992 return PJ_SUCCESS; 2993 } 2994 2995 2996 2997 /* 2998 * Create stream info from SDP media line. 2999 */ 3000 PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp( 3001 pjmedia_stream_info *si, 3002 pj_pool_t *pool, 3003 pjmedia_endpt *endpt, 3004 const pjmedia_sdp_session *local, 3005 const pjmedia_sdp_session *remote, 3006 unsigned stream_idx) 3007 { 3008 pjmedia_codec_mgr *mgr; 3009 const pjmedia_sdp_attr *attr; 3010 const pjmedia_sdp_media *local_m; 3011 const pjmedia_sdp_media *rem_m; 3012 const pjmedia_sdp_conn *local_conn; 3013 const pjmedia_sdp_conn *rem_conn; 3014 int rem_af, local_af; 3015 pj_sockaddr local_addr; 3016 pj_status_t status; 3017 3018 3019 /* Validate arguments: */ 3020 PJ_ASSERT_RETURN(pool && si && local && remote, PJ_EINVAL); 3021 PJ_ASSERT_RETURN(stream_idx < local->media_count, PJ_EINVAL); 3022 PJ_ASSERT_RETURN(stream_idx < remote->media_count, PJ_EINVAL); 3023 3024 /* Keep SDP shortcuts */ 3025 local_m = local->media[stream_idx]; 3026 rem_m = remote->media[stream_idx]; 3027 3028 local_conn = local_m->conn ? local_m->conn : local->conn; 3029 if (local_conn == NULL) 3030 return PJMEDIA_SDP_EMISSINGCONN; 3031 3032 rem_conn = rem_m->conn ? rem_m->conn : remote->conn; 3033 if (rem_conn == NULL) 3034 return PJMEDIA_SDP_EMISSINGCONN; 3035 3036 /* Media type must be audio */ 3037 if (pj_stricmp(&local_m->desc.media, &ID_AUDIO) == 0) 3038 return PJMEDIA_EINVALIMEDIATYPE; 3039 3040 /* Get codec manager. */ 3041 mgr = pjmedia_endpt_get_codec_mgr(endpt); 3042 3043 /* Reset: */ 3044 3045 pj_bzero(si, sizeof(*si)); 3046 3047 #if PJMEDIA_HAS_RTCP_XR && PJMEDIA_STREAM_ENABLE_XR 3048 /* Set default RTCP XR enabled/disabled */ 3049 si->rtcp_xr_enabled = PJ_TRUE; 3050 #endif 3051 3052 /* Media type: */ 3053 si->type = PJMEDIA_TYPE_AUDIO; 3054 3055 /* Transport protocol */ 3056 3057 /* At this point, transport type must be compatible, 3058 * the transport instance will do more validation later. 3059 */ 3060 status = pjmedia_sdp_transport_cmp(&rem_m->desc.transport, 3061 &local_m->desc.transport); 3062 if (status != PJ_SUCCESS) 3063 return PJMEDIA_SDPNEG_EINVANSTP; 3064 3065 if (pj_stricmp(&local_m->desc.transport, &ID_RTP_AVP) == 0) { 3066 3067 si->proto = PJMEDIA_TP_PROTO_RTP_AVP; 3068 3069 } else if (pj_stricmp(&local_m->desc.transport, &ID_RTP_SAVP) == 0) { 3070 3071 si->proto = PJMEDIA_TP_PROTO_RTP_SAVP; 3072 3073 } else { 3074 3075 si->proto = PJMEDIA_TP_PROTO_UNKNOWN; 3076 return PJ_SUCCESS; 3077 } 3078 3079 3080 /* Check address family in remote SDP */ 3081 rem_af = pj_AF_UNSPEC(); 3082 if (pj_stricmp(&rem_conn->net_type, &ID_IN)==0) { 3083 if (pj_stricmp(&rem_conn->addr_type, &ID_IP4)==0) { 3084 rem_af = pj_AF_INET(); 3085 } else if (pj_stricmp(&rem_conn->addr_type, &ID_IP6)==0) { 3086 rem_af = pj_AF_INET6(); 3087 } 3088 } 3089 3090 if (rem_af==pj_AF_UNSPEC()) { 3091 /* Unsupported address family */ 3092 return PJ_EAFNOTSUP; 3093 } 3094 3095 /* Set remote address: */ 3096 status = pj_sockaddr_init(rem_af, &si->rem_addr, &rem_conn->addr, 3097 rem_m->desc.port); 3098 if (status != PJ_SUCCESS) { 3099 /* Invalid IP address. */ 3100 return PJMEDIA_EINVALIDIP; 3101 } 3102 3103 /* Check address family of local info */ 3104 local_af = pj_AF_UNSPEC(); 3105 if (pj_stricmp(&local_conn->net_type, &ID_IN)==0) { 3106 if (pj_stricmp(&local_conn->addr_type, &ID_IP4)==0) { 3107 local_af = pj_AF_INET(); 3108 } else if (pj_stricmp(&local_conn->addr_type, &ID_IP6)==0) { 3109 local_af = pj_AF_INET6(); 3110 } 3111 } 3112 3113 if (local_af==pj_AF_UNSPEC()) { 3114 /* Unsupported address family */ 3115 return PJ_SUCCESS; 3116 } 3117 3118 /* Set remote address: */ 3119 status = pj_sockaddr_init(local_af, &local_addr, &local_conn->addr, 3120 local_m->desc.port); 3121 if (status != PJ_SUCCESS) { 3122 /* Invalid IP address. */ 3123 return PJMEDIA_EINVALIDIP; 3124 } 3125 3126 /* Local and remote address family must match */ 3127 if (local_af != rem_af) 3128 return PJ_EAFNOTSUP; 3129 3130 /* Media direction: */ 3131 3132 if (local_m->desc.port == 0 || 3133 pj_sockaddr_has_addr(&local_addr)==PJ_FALSE || 3134 pj_sockaddr_has_addr(&si->rem_addr)==PJ_FALSE || 3135 pjmedia_sdp_media_find_attr(local_m, &STR_INACTIVE, NULL)!=NULL) 3136 { 3137 /* Inactive stream. */ 3138 3139 si->dir = PJMEDIA_DIR_NONE; 3140 3141 } else if (pjmedia_sdp_media_find_attr(local_m, &STR_SENDONLY, NULL)!=NULL) { 3142 3143 /* Send only stream. */ 3144 3145 si->dir = PJMEDIA_DIR_ENCODING; 3146 3147 } else if (pjmedia_sdp_media_find_attr(local_m, &STR_RECVONLY, NULL)!=NULL) { 3148 3149 /* Recv only stream. */ 3150 3151 si->dir = PJMEDIA_DIR_DECODING; 3152 3153 } else { 3154 3155 /* Send and receive stream. */ 3156 3157 si->dir = PJMEDIA_DIR_ENCODING_DECODING; 3158 3159 } 3160 3161 /* No need to do anything else if stream is rejected */ 3162 if (local_m->desc.port == 0) { 3163 return PJ_SUCCESS; 3164 } 3165 3166 /* If "rtcp" attribute is present in the SDP, set the RTCP address 3167 * from that attribute. Otherwise, calculate from RTP address. 3168 */ 3169 attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 3170 "rtcp", NULL); 3171 if (attr) { 3172 pjmedia_sdp_rtcp_attr rtcp; 3173 status = pjmedia_sdp_attr_get_rtcp(attr, &rtcp); 3174 if (status == PJ_SUCCESS) { 3175 if (rtcp.addr.slen) { 3176 status = pj_sockaddr_init(rem_af, &si->rem_rtcp, &rtcp.addr, 3177 (pj_uint16_t)rtcp.port); 3178 } else { 3179 pj_sockaddr_init(rem_af, &si->rem_rtcp, NULL, 3180 (pj_uint16_t)rtcp.port); 3181 pj_memcpy(pj_sockaddr_get_addr(&si->rem_rtcp), 3182 pj_sockaddr_get_addr(&si->rem_addr), 3183 pj_sockaddr_get_addr_len(&si->rem_addr)); 3184 } 3185 } 3186 } 3187 3188 if (!pj_sockaddr_has_addr(&si->rem_rtcp)) { 3189 int rtcp_port; 3190 3191 pj_memcpy(&si->rem_rtcp, &si->rem_addr, sizeof(pj_sockaddr)); 3192 rtcp_port = pj_sockaddr_get_port(&si->rem_addr) + 1; 3193 pj_sockaddr_set_port(&si->rem_rtcp, (pj_uint16_t)rtcp_port); 3194 } 3195 3196 3197 /* Get the payload number for receive channel. */ 3198 /* 3199 Previously we used to rely on fmt[0] being the selected codec, 3200 but some UA sends telephone-event as fmt[0] and this would 3201 cause assert failure below. 3202 3203 Thanks Chris Hamilton <chamilton .at. cs.dal.ca> for this patch. 3204 3205 // And codec must be numeric! 3206 if (!pj_isdigit(*local_m->desc.fmt[0].ptr) || 3207 !pj_isdigit(*rem_m->desc.fmt[0].ptr)) 3208 { 3209 return PJMEDIA_EINVALIDPT; 3210 } 3211 3212 pt = pj_strtoul(&local_m->desc.fmt[0]); 3213 pj_assert(PJMEDIA_RTP_PT_TELEPHONE_EVENTS==0 || 3214 pt != PJMEDIA_RTP_PT_TELEPHONE_EVENTS); 3215 */ 3216 3217 /* Get codec info and param */ 3218 status = get_audio_codec_info_param(si, pool, mgr, local_m, rem_m); 3219 3220 /* Leave SSRC to random. */ 3221 si->ssrc = pj_rand(); 3222 3223 /* Set default jitter buffer parameter. */ 3224 si->jb_init = si->jb_max = si->jb_min_pre = si->jb_max_pre = -1; 3225 3226 return status; 3227 } -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_codec.c
r3392 r3420 29 29 static pjmedia_vid_codec_mgr *def_vid_codec_mgr; 30 30 31 /* Definition of default codecs parameters */ 32 struct pjmedia_vid_codec_default_param 33 { 34 pjmedia_vid_codec_param *param; 31 32 /* 33 * Codec manager maintains array of these structs for each supported 34 * codec. 35 */ 36 typedef struct pjmedia_vid_codec_desc 37 { 38 pjmedia_vid_codec_info info; /**< Codec info. */ 39 pjmedia_codec_id id; /**< Fully qualified name */ 40 pjmedia_codec_priority prio; /**< Priority. */ 41 pjmedia_vid_codec_factory *factory; /**< The factory. */ 42 pjmedia_vid_codec_param *def_param; /**< Default codecs 43 parameters. */ 44 } pjmedia_vid_codec_desc; 45 46 47 /* The declaration of video codec manager */ 48 struct pjmedia_vid_codec_mgr 49 { 50 /** Codec manager mutex. */ 51 pj_mutex_t *mutex; 52 53 /** List of codec factories registered to codec manager. */ 54 pjmedia_vid_codec_factory factory_list; 55 56 /** Number of supported codecs. */ 57 unsigned codec_cnt; 58 59 /** Array of codec descriptor. */ 60 pjmedia_vid_codec_desc codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS]; 61 35 62 }; 63 36 64 37 65 … … 94 122 PJ_DEF(pjmedia_vid_codec_mgr*) pjmedia_vid_codec_mgr_instance(void) 95 123 { 96 pj_assert(def_vid_codec_mgr);124 //pj_assert(def_vid_codec_mgr); 97 125 return def_vid_codec_mgr; 98 126 } … … 616 644 ¶m->dec_fmtp.param[i].val); 617 645 } 618 for (i = 0; i < param-> dec_fmtp.cnt; ++i) {619 pj_strdup(pool, &p-> dec_fmtp.param[i].name,620 ¶m-> dec_fmtp.param[i].name);621 pj_strdup(pool, &p-> dec_fmtp.param[i].val,622 ¶m-> dec_fmtp.param[i].val);646 for (i = 0; i < param->enc_fmtp.cnt; ++i) { 647 pj_strdup(pool, &p->enc_fmtp.param[i].name, 648 ¶m->enc_fmtp.param[i].name); 649 pj_strdup(pool, &p->enc_fmtp.param[i].val, 650 ¶m->enc_fmtp.param[i].val); 623 651 } 624 652 -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/videoport.c
r3402 r3420 38 38 pjmedia_dir dir; 39 39 pjmedia_rect_size cap_size; 40 pjmedia_vid_ stream *strm;40 pjmedia_vid_dev_stream *strm; 41 41 pjmedia_vid_cb strm_cb; 42 42 void *strm_cb_data; … … 75 75 }; 76 76 77 static pj_status_t vidstream_cap_cb(pjmedia_vid_ stream *stream,77 static pj_status_t vidstream_cap_cb(pjmedia_vid_dev_stream *stream, 78 78 void *user_data, 79 79 pjmedia_frame *frame); 80 static pj_status_t vidstream_render_cb(pjmedia_vid_ stream *stream,80 static pj_status_t vidstream_render_cb(pjmedia_vid_dev_stream *stream, 81 81 void *user_data, 82 82 pjmedia_frame *frame); 83 static pj_status_t vidstream_event_cb(pjmedia_vid_ stream *stream,83 static pj_status_t vidstream_event_cb(pjmedia_vid_dev_stream *stream, 84 84 void *user_data, 85 85 pjmedia_vid_event *event); … … 171 171 vid_cb.on_event_cb = &vidstream_event_cb; 172 172 173 status = pjmedia_vid_ stream_create(&prm->vidparam, &vid_cb, vp,174 &vp->strm);173 status = pjmedia_vid_dev_stream_create(&prm->vidparam, &vid_cb, vp, 174 &vp->strm); 175 175 if (status != PJ_SUCCESS) 176 176 goto on_error; … … 278 278 } 279 279 280 PJ_DEF(pjmedia_vid_ stream*)280 PJ_DEF(pjmedia_vid_dev_stream*) 281 281 pjmedia_vid_port_get_stream(pjmedia_vid_port *vp) 282 282 { … … 357 357 PJ_ASSERT_RETURN(vp, PJ_EINVAL); 358 358 359 status = pjmedia_vid_ stream_start(vp->strm);359 status = pjmedia_vid_dev_stream_start(vp->strm); 360 360 if (status != PJ_SUCCESS) 361 361 goto on_error; … … 386 386 PJ_ASSERT_RETURN(vp, PJ_EINVAL); 387 387 388 status = pjmedia_vid_ stream_stop(vp->strm);388 status = pjmedia_vid_dev_stream_stop(vp->strm); 389 389 390 390 if (vp->enc_clock) { … … 414 414 } 415 415 if (vp->strm) { 416 pjmedia_vid_ stream_destroy(vp->strm);416 pjmedia_vid_dev_stream_destroy(vp->strm); 417 417 vp->strm = NULL; 418 418 } … … 478 478 return; 479 479 480 status = pjmedia_vid_ stream_get_frame(vp->strm, vp->enc_frm_buf);480 status = pjmedia_vid_dev_stream_get_frame(vp->strm, vp->enc_frm_buf); 481 481 if (status != PJ_SUCCESS) 482 482 return; … … 581 581 } else 582 582 vp->rend_sync_clocksrc.nsync_progress += ndrop; 583 583 584 for (i = 0; i < ndrop; i++) { 584 585 status = pjmedia_port_get_frame(vp->client_port, … … 603 604 pjmedia_clock_src_update(&vp->rend_clocksrc, NULL); 604 605 605 status = pjmedia_vid_ stream_put_frame(vp->strm, vp->dec_frm_buf);606 status = pjmedia_vid_dev_stream_put_frame(vp->strm, vp->dec_frm_buf); 606 607 } 607 608 … … 615 616 } 616 617 617 static pj_status_t vidstream_cap_cb(pjmedia_vid_ stream *stream,618 static pj_status_t vidstream_cap_cb(pjmedia_vid_dev_stream *stream, 618 619 void *user_data, 619 620 pjmedia_frame *frame) … … 634 635 } 635 636 636 static pj_status_t vidstream_render_cb(pjmedia_vid_ stream *stream,637 static pj_status_t vidstream_render_cb(pjmedia_vid_dev_stream *stream, 637 638 void *user_data, 638 639 pjmedia_frame *frame) … … 653 654 } 654 655 655 static pj_status_t vidstream_event_cb(pjmedia_vid_ stream *stream,656 static pj_status_t vidstream_event_cb(pjmedia_vid_dev_stream *stream, 656 657 void *user_data, 657 658 pjmedia_vid_event *event) … … 671 672 672 673 if (vp->stream_role==ROLE_PASSIVE) { 673 return pjmedia_vid_ stream_put_frame(vp->strm, frame);674 return pjmedia_vid_dev_stream_put_frame(vp->strm, frame); 674 675 } else { 675 676 pj_mutex_lock(vp->dec_frm_mutex); … … 688 689 689 690 if (vp->stream_role==ROLE_PASSIVE) { 690 return pjmedia_vid_ stream_get_frame(vp->strm, frame);691 return pjmedia_vid_dev_stream_get_frame(vp->strm, frame); 691 692 } else { 692 693 pj_mutex_lock(vp->enc_frm_mutex);
Note: See TracChangeset
for help on using the changeset viewer.