- Timestamp:
- Sep 29, 2011 8:31:15 AM (13 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia-codec/ffmpeg_codecs.h
r3715 r3776 27 27 PJ_BEGIN_DECL 28 28 29 /** 30 * @defgroup PJMEDIA_CODEC_VID_FFMPEG FFmpeg Codecs 31 * @ingroup PJMEDIA_CODEC_VID_CODECS 32 * @{ 33 */ 29 34 30 35 /** -
pjproject/trunk/pjmedia/include/pjmedia/vid_codec.h
r3715 r3776 36 36 PJ_BEGIN_DECL 37 37 38 /** 39 * @defgroup PJMEDIA_VID_CODEC Video Codecs 40 * @ingroup PJMEDIA_CODEC 41 * @{ 42 */ 43 38 44 #define PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT 8 39 45 #define PJMEDIA_VID_CODEC_MAX_FPS_CNT 16 46 47 /** 48 * This enumeration specifies the packetization property of video encoding 49 * process. The value is bitmask, and smaller value will have higher priority 50 * to be used. 51 */ 52 typedef enum pjmedia_vid_packing 53 { 54 /** 55 * This specifies that the packetization is unknown, or if nothing 56 * is supported. 57 */ 58 PJMEDIA_VID_PACKING_UNKNOWN, 59 60 /** 61 * This specifies that the result of video encoding process will be 62 * segmented into packets, which is suitable for RTP transmission. 63 * The maximum size of the packets is set in \a enc_mtu field of 64 * pjmedia_vid_codec_param. 65 */ 66 PJMEDIA_VID_PACKING_PACKETS = 1, 67 68 /** 69 * This specifies that video encoding function will produce a whole 70 * or full frame from the source frame. This is normally used for 71 * encoding video for offline storage such as to an AVI file. The 72 * maximum size of the packets is set in \a enc_mtu field of 73 * pjmedia_vid_codec_param. 74 */ 75 PJMEDIA_VID_PACKING_WHOLE = 2 76 77 } pjmedia_vid_packing; 40 78 41 79 /** … … 56 94 /**< Supported encoding source 57 95 format IDs */ 96 unsigned packings; /**< Supported or requested packings, 97 strategies, bitmask from 98 pjmedia_vid_packing */ 58 99 unsigned fps_cnt; /**< # of supported frame-rates, can be 59 100 zero (support any frame-rate) */ 60 101 pjmedia_ratio fps[PJMEDIA_VID_CODEC_MAX_FPS_CNT]; 61 102 /**< Supported frame-rates */ 62 pj_bool_t has_rtp_pack; /**< Support RTP packetization */ 103 63 104 } pjmedia_vid_codec_info; 64 105 … … 77 118 { 78 119 pjmedia_dir dir; /**< Direction */ 120 pjmedia_vid_packing packing; /**< Packetization strategy. */ 121 79 122 pjmedia_format enc_fmt; /**< Encoded format */ 123 pjmedia_codec_fmtp enc_fmtp; /**< Encoder fmtp params */ 124 unsigned enc_mtu; /**< MTU or max payload size setting*/ 125 80 126 pjmedia_format dec_fmt; /**< Decoded format */ 81 82 pjmedia_codec_fmtp enc_fmtp; /**< Encoder fmtp params */83 127 pjmedia_codec_fmtp dec_fmtp; /**< Decoder fmtp params */ 84 128 85 unsigned enc_mtu; /**< MTU or max payload size setting*/86 129 } pjmedia_vid_codec_param; 87 130 … … 112 155 { 113 156 /** 114 * Initialize codec using the specified attribute. 115 * 116 * Application should call #pjmedia_vid_codec_init() instead of 117 * calling this function directly. 118 * 119 * @param codec The codec instance. 120 * @param pool Pool to use when the codec needs to allocate 121 * some memory. 122 * 123 * @return PJ_SUCCESS on success. 157 * See #pjmedia_vid_codec_init(). 124 158 */ 125 159 pj_status_t (*init)(pjmedia_vid_codec *codec, … … 127 161 128 162 /** 129 * Open the codec and initialize with the specified parameter. 130 * Upon successful initialization, the codec may modify the parameter 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). 134 * 135 * Application should call #pjmedia_vid_codec_open() instead of 136 * calling this function directly. 137 * 138 * @param codec The codec instance. 139 * @param param Codec initialization parameter. 140 * 141 * @return PJ_SUCCESS on success. 163 * See #pjmedia_vid_codec_open(). 142 164 */ 143 165 pj_status_t (*open)(pjmedia_vid_codec *codec, … … 145 167 146 168 /** 147 * Close and shutdown codec, releasing all resources allocated by 148 * this codec, if any. 149 * 150 * Application should call #pjmedia_vid_codec_close() instead of 151 * calling this function directly. 152 * 153 * @param codec The codec instance. 154 * 155 * @return PJ_SUCCESS on success. 169 * See #pjmedia_vid_codec_close(). 156 170 */ 157 171 pj_status_t (*close)(pjmedia_vid_codec *codec); 158 172 159 173 /** 160 * Modify the codec parameter after the codec is open. 161 * Note that not all codec parameters can be modified during run-time. 162 * When the parameter cannot be changed, this function will return 163 * non-PJ_SUCCESS, and the original parameters will not be changed. 164 * 165 * Application should call #pjmedia_vid_codec_modify() instead of 166 * calling this function directly. 167 * 168 * @param codec The codec instance. 169 * @param param The new codec parameter. 170 * 171 * @return PJ_SUCCESS on success. 174 * See #pjmedia_vid_codec_modify(). 172 175 */ 173 176 pj_status_t (*modify)(pjmedia_vid_codec *codec, … … 175 178 176 179 /** 177 * Get the codec parameter after the codec is opened. 178 * 179 * Application should call #pjmedia_vid_codec_get_param() instead of 180 * calling this function directly. 181 * 182 * @param codec The codec instance. 183 * @param param The codec parameter. 184 * 185 * @return PJ_SUCCESS on success. 180 * See #pjmedia_vid_codec_get_param(). 186 181 */ 187 182 pj_status_t (*get_param)(pjmedia_vid_codec *codec, … … 189 184 190 185 /** 191 * Instruct the codec to generate a payload/packet from a picture 192 * bitstream to be sent (via network). The maximum payload size or 193 * MTU is configurable via enc_mtu field of #pjmedia_vid_codec_param. 194 * For a long bitstream, application usually need to call this function 195 * multiple times until the whole bitstream is sent. Note that, for 196 * performance reason, the packetization will be done in-place, so the 197 * original bitstream may be modified by this function. 198 * 199 * Application should call #pjmedia_vid_codec_packetize() instead of 200 * calling this function directly. 201 * 202 * @param codec The codec instance 203 * @param bits The picture bitstream. 204 * @param bits_len The length of the bitstream. 205 * @param bits_pos On input, the start position of the bitstream 206 * to be packetized. On output, the next position for 207 * next packet. 208 * @param pkt The pointer of the generated payload. 209 * @param pkt_len The payload length. 210 * 211 * @return PJ_SUCCESS on success. 212 */ 213 pj_status_t (*packetize) (pjmedia_vid_codec *codec, 214 pj_uint8_t *bits, 215 pj_size_t bits_len, 216 unsigned *bits_pos, 217 const pj_uint8_t **pkt, 218 pj_size_t *pkt_len); 186 * See #pjmedia_vid_codec_encode_begin(). 187 */ 188 pj_status_t (*encode_begin)(pjmedia_vid_codec *codec, 189 const pjmedia_frame *input, 190 unsigned out_size, 191 pjmedia_frame *output, 192 pj_bool_t *has_more); 219 193 220 194 /** 221 * Instruct the codec to parse a payload and append it into a picture 222 * bitstream. A picture bitstreams may need to be reconstructed from 223 * one or more payloads. Note that this function will not provide the 224 * detection of picture boundary, so application should manage the 225 * picture boundary detection by itself, e.g: for RTP delivery, payloads 226 * belong to the same picture will share the same RTP timestamp and also 227 * there is marker bit in the RTP header that is usually reserved for 228 * end-of-picture flag. Also note that in case of noticing packet lost, 229 * application should keep calling this function with payload pointer 230 * set to NULL, as the packetizer need to update its internal state. 231 * 232 * Application should call #pjmedia_vid_codec_unpacketize() instead of 233 * calling this function directly. 234 * 235 * @param codec The codec instance 236 * @param pkt The input packet. 237 * @param pkt_size Size of the packet. 238 * @param timestamp The timestamp of the first sample in the packet. 239 * @param frame_cnt On input, specifies the maximum number of frames 240 * in the array. On output, the codec must fill 241 * with number of frames detected in the packet. 242 * @param frames On output, specifies the frames that have been 243 * detected in the packet. 244 * 245 * @return PJ_SUCCESS on success. 246 */ 247 pj_status_t (*unpacketize)(pjmedia_vid_codec *codec, 248 const pj_uint8_t *payload, 249 pj_size_t payload_len, 250 pj_uint8_t *bits, 251 pj_size_t bits_len, 252 unsigned *bits_pos); 253 254 /** 255 * Instruct the codec to encode the specified input frame. The input 256 * MUST contain only one picture with appropriate format as specified 257 * in opening the codec. 258 * 259 * Application should call #pjmedia_vid_codec_encode() instead of 260 * calling this function directly. 261 * 262 * @param codec The codec instance. 263 * @param input The input frame. 264 * @param out_size The length of buffer in the output frame. 265 * @param output The output frame. 266 * 267 * @return PJ_SUCCESS on success; 268 */ 269 pj_status_t (*encode)(pjmedia_vid_codec *codec, 270 const pjmedia_frame *input, 271 unsigned out_size, 195 * See #pjmedia_vid_codec_encode_more() 196 */ 197 pj_status_t (*encode_more)(pjmedia_vid_codec *codec, 198 unsigned out_size, 199 pjmedia_frame *output, 200 pj_bool_t *has_more); 201 202 203 /* 204 * See #pjmedia_vid_codec_decode(). 205 */ 206 pj_status_t (*decode)(pjmedia_vid_codec *codec, 207 pj_size_t count, 208 pjmedia_frame packets[], 209 unsigned out_size, 272 210 pjmedia_frame *output); 273 211 274 /**275 * Instruct the codec to decode the specified input frame. The input276 * frame MUST contain exactly one picture. Note that the decoded picture277 * format may different to the current setting, e.g: the format specified278 * in the #pjmedia_vid_codec_param when opening the codec, in this case the279 * PJMEDIA_EVENT_FMT_CHANGED event will be emitted by the codec. The codec280 * parameter will also be updated, and application can query the format by281 * using #get_param().282 *283 * Application should call #pjmedia_vid_codec_decode() instead of284 * calling this function directly.285 *286 * @param codec The codec instance.287 * @param input The input frame.288 * @param out_size The length of buffer in the output frame.289 * @param output The output frame.290 *291 * @return PJ_SUCCESS on success;292 */293 pj_status_t (*decode)(pjmedia_vid_codec *codec,294 const pjmedia_frame *input,295 unsigned out_size,296 pjmedia_frame *output);297 298 212 /** 299 * Instruct the codec to recover a missing frame. 300 * 301 * Application should call #pjmedia_vid_codec_recover() instead of 302 * calling this function directly. 303 * 304 * @param codec The codec instance. 305 * @param out_size The length of buffer in the output frame. 306 * @param output The output frame where generated signal 307 * will be placed. 308 * 309 * @return PJ_SUCCESS on success; 213 * See #pjmedia_vid_codec_recover() 310 214 */ 311 215 pj_status_t (*recover)(pjmedia_vid_codec *codec, … … 554 458 * @return PJ_SUCCESS on success. 555 459 */ 556 PJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_enum_codecs(557 pjmedia_vid_codec_mgr *mgr, 558 unsigned *count,559 560 460 PJ_DECL(pj_status_t) 461 pjmedia_vid_codec_mgr_enum_codecs(pjmedia_vid_codec_mgr *mgr, 462 unsigned *count, 463 pjmedia_vid_codec_info info[], 464 unsigned *prio); 561 465 562 466 … … 605 509 * the buffer is not long enough. 606 510 */ 607 PJ_DECL(char*) pjmedia_vid_codec_info_to_id( 608 const pjmedia_vid_codec_info *info, 609 char *id, unsigned max_len ); 511 PJ_DECL(char*) pjmedia_vid_codec_info_to_id(const pjmedia_vid_codec_info *info, 512 char *id, unsigned max_len ); 610 513 611 514 … … 758 661 * @return PJ_SUCCESS on success. 759 662 */ 760 PJ_INLINE(pj_status_t) pjmedia_vid_codec_open( 761 pjmedia_vid_codec *codec, 762 pjmedia_vid_codec_param *param ) 663 PJ_INLINE(pj_status_t) pjmedia_vid_codec_open(pjmedia_vid_codec *codec, 664 pjmedia_vid_codec_param *param) 763 665 { 764 666 return (*codec->op->open)(codec, param); … … 791 693 * @return PJ_SUCCESS on success. 792 694 */ 793 PJ_INLINE(pj_status_t) pjmedia_vid_codec_modify(794 pjmedia_vid_codec *codec, 795 695 PJ_INLINE(pj_status_t) 696 pjmedia_vid_codec_modify(pjmedia_vid_codec *codec, 697 const pjmedia_vid_codec_param *param) 796 698 { 797 699 return (*codec->op->modify)(codec, param); … … 807 709 * @return PJ_SUCCESS on success. 808 710 */ 809 PJ_INLINE(pj_status_t) pjmedia_vid_codec_get_param(810 pjmedia_vid_codec *codec, 811 711 PJ_INLINE(pj_status_t) 712 pjmedia_vid_codec_get_param(pjmedia_vid_codec *codec, 713 pjmedia_vid_codec_param *param) 812 714 { 813 715 return (*codec->op->get_param)(codec, param); 814 716 } 815 717 816 817 /** 818 * Instruct the codec to generate a payload/packet from a picture819 * bitstream to be sent (via network). The maximum payload size or820 * MTU is configurable via enc_mtu field of #pjmedia_vid_codec_param.821 * For a long bitstream, application usually need to call this function822 * multiple times until the whole bitstream is sent. Note that, for823 * performance reason, the packetization will be done in-place, sothe824 * original bitstream may be modified by this function.825 * 826 * @param codec The codec instance827 * @param bits The picture bitstream.828 * @param bits_len The length of the bitstream.829 * @param bits_pos On input, the start position of the bitstream830 * to be packetized. On output, the next position for831 * next packet.832 * @param pkt The pointer of the generated payload.833 * @param pkt_len The payload length.834 * 835 * @return PJ_SUCCESS on success.836 * /837 PJ_INLINE(pj_status_t) pjmedia_vid_codec_packetize( 838 pjmedia_vid_codec *codec, 839 pj_uint8_t *bits,840 pj_size_t bits_len,841 unsigned *bits_pos,842 const pj_uint8_t **pkt,843 pj_size_t *pkt_len)844 { 845 return (*codec->op-> packetize)(codec, bits, bits_len, bits_pos,846 pkt, pkt_len);718 /** 719 * Encode the specified input frame. The input MUST contain only one picture 720 * with the appropriate format as specified when opening the codec. Depending 721 * on the packing or packetization set in the \a packing param, the process 722 * may produce multiple encoded packets or payloads to represent the picture. 723 * This is true for example for PJMEDIA_VID_PACKING_PACKETS packing. In this 724 * case, the \a has_more field will be set to PJ_TRUE, and application should 725 * call pjmedia_vid_codec_encode_more() to get the remaining results from the 726 * codec. 727 * 728 * @param codec The codec instance. 729 * @param input The input frame. 730 * @param out_size The length of buffer in the output frame. This 731 * should be at least the same as the configured 732 * encoding MTU of the codec. 733 * @param output The output frame. 734 * @param has_more PJ_TRUE if more payloads are available; application 735 * should then call pjmedia_vid_codec_encode_more() 736 * to retrieve the remaining results. 737 * 738 * @return PJ_SUCCESS on success; 739 */ 740 PJ_INLINE(pj_status_t) 741 pjmedia_vid_codec_encode_begin( pjmedia_vid_codec *codec, 742 const pjmedia_frame *input, 743 unsigned out_size, 744 pjmedia_frame *output, 745 pj_bool_t *has_more) 746 { 747 return (*codec->op->encode_begin)(codec, input, out_size, output, 748 has_more); 847 749 } 848 750 849 850 /** 851 * Instruct the codec to parse a payload and append it into a picture 852 * bitstream. A picture bitstreams may need to be reconstructed from 853 * one or more payloads. Note that this function will not provide the 854 * detection of picture boundary, so application should manage the 855 * picture boundary detection by itself, e.g: for RTP delivery, payloads 856 * belong to the same picture will share the same RTP timestamp and also 857 * there is marker bit in the RTP header that is usually reserved for 858 * end-of-picture flag. Also note that in case of noticing packet lost, 859 * application should keep calling this function with payload pointer 860 * set to NULL, as the packetizer need to update its internal state. 861 * 862 * @param codec The codec instance 863 * @param pkt The input packet. 864 * @param pkt_size Size of the packet. 865 * @param timestamp The timestamp of the first sample in the packet. 866 * @param frame_cnt On input, specifies the maximum number of frames 867 * in the array. On output, the codec must fill 868 * with number of frames detected in the packet. 869 * @param frames On output, specifies the frames that have been 870 * detected in the packet. 871 * 872 * @return PJ_SUCCESS on success. 873 */ 874 PJ_INLINE(pj_status_t) pjmedia_vid_codec_unpacketize( 875 pjmedia_vid_codec *codec, 876 const pj_uint8_t *payload, 877 pj_size_t payload_len, 878 pj_uint8_t *bits, 879 pj_size_t bits_len, 880 unsigned *bits_pos ) 881 { 882 return (*codec->op->unpacketize)(codec, payload, payload_len, bits, 883 bits_len, bits_pos); 751 /** 752 * Retrieve more encoded packets/payloads from the codec. Application 753 * should call this function repeatedly until \a has_more flag is set 754 * to PJ_FALSE. 755 * 756 * @param codec The codec instance. 757 * @param out_size The length of buffer in the output frame. This 758 * should be at least the same as as the configured 759 * encoding MTU of the codec. 760 * @param output The output frame. 761 * @param has_more PJ_TRUE if more payloads are available, which in 762 * this case application should call \a encode_more() 763 * to retrieve them. 764 * 765 * @return PJ_SUCCESS on success; 766 */ 767 PJ_INLINE(pj_status_t) 768 pjmedia_vid_codec_encode_more( pjmedia_vid_codec *codec, 769 unsigned out_size, 770 pjmedia_frame *output, 771 pj_bool_t *has_more) 772 { 773 return (*codec->op->encode_more)(codec, out_size, output, has_more); 884 774 } 885 775 886 887 /** 888 * Instruct the codec to encode the specified input frame. The input 889 * MUST contain only one picture with appropriate format as specified 890 * in opening the codec. 891 * 892 * @param codec The codec instance. 893 * @param input The input frame. 776 /** 777 * Decode the input packets into one picture. If the packing is set to 778 * PJMEDIA_VID_PACKING_PACKETS when opening the codec, the codec is set 779 * to decode multiple encoded packets into one picture. These encoded 780 * packets are typically retrieved from the jitter buffer. If the packing 781 * is set to PJMEDIA_VID_PACKING_WHOLE, then this decode function can only 782 * accept one frame as the input. 783 * 784 * Note that the decoded picture format may different to the configured 785 * setting (i.e. the format specified in the #pjmedia_vid_codec_param when 786 * opening the codec), in this case the PJMEDIA_EVENT_FMT_CHANGED event will 787 * be emitted by the codec to notify the event. The codec parameter will 788 * also be updated, and application can query the format by using 789 * pjmedia_vid_codec_get_param(). 790 * 791 * @param codec The codec instance. 792 * @param pkt_count Number of packets in the input. 793 * @param packets Array of input packets, each containing an encoded 794 * frame. 894 795 * @param out_size The length of buffer in the output frame. 895 796 * @param output The output frame. … … 897 798 * @return PJ_SUCCESS on success; 898 799 */ 899 PJ_INLINE(pj_status_t) pjmedia_vid_codec_ encode(900 pjmedia_vid_codec *codec,901 const pjmedia_frame *input,902 unsigned out_size,903 904 { 905 return (*codec->op-> encode)(codec, input, out_size, output);800 PJ_INLINE(pj_status_t) pjmedia_vid_codec_decode(pjmedia_vid_codec *codec, 801 pj_size_t pkt_count, 802 pjmedia_frame packets[], 803 unsigned out_size, 804 pjmedia_frame *output) 805 { 806 return (*codec->op->decode)(codec, pkt_count, packets, out_size, output); 906 807 } 907 808 908 909 /** 910 * Instruct the codec to decode the specified input frame. The input 911 * frame MUST contain exactly one picture. Note that the decoded picture 912 * format may different to the current setting, e.g: the format specified 913 * in the #pjmedia_vid_codec_param when opening the codec, in this case the 914 * PJMEDIA_EVENT_FMT_CHANGED event will be emitted by the codec. The codec 915 * parameter will also be updated, and application can query the format by 916 * using #get_param(). 917 * 918 * @param codec The codec instance. 919 * @param input The input frame. 920 * @param out_size The length of buffer in the output frame. 921 * @param output The output frame. 922 * 923 * @return PJ_SUCCESS on success; 924 */ 925 PJ_INLINE(pj_status_t) pjmedia_vid_codec_decode( 926 pjmedia_vid_codec *codec, 927 const pjmedia_frame *input, 928 unsigned out_size, 929 pjmedia_frame *output) 930 { 931 return (*codec->op->decode)(codec, input, out_size, output); 932 } 933 934 935 /** 936 * Instruct the codec to recover a missing frame. 937 * 938 * @param codec The codec instance. 809 /** 810 * Recover a missing frame. 811 * 812 * @param codec The codec instance. 939 813 * @param out_size The length of buffer in the output frame. 940 814 * @param output The output frame where generated signal … … 943 817 * @return PJ_SUCCESS on success; 944 818 */ 945 PJ_INLINE(pj_status_t) pjmedia_vid_codec_recover( 946 pjmedia_vid_codec *codec, 947 unsigned out_size, 948 pjmedia_frame *output) 819 PJ_INLINE(pj_status_t) pjmedia_vid_codec_recover(pjmedia_vid_codec *codec, 820 unsigned out_size, 821 pjmedia_frame *output) 949 822 { 950 823 if (codec->op && codec->op->recover) … … 961 834 /** 962 835 * @defgroup PJMEDIA_CODEC_VID_CODECS Supported video codecs 963 * @ingroup PJMEDIA_CODEC 964 * @brief Documentation about individual video codec supported by PJMEDIA 965 * @{ 966 * Please see the APIs provided by the individual codecs below. 967 */ 968 /** 969 * @} 836 * @ingroup PJMEDIA_VID_CODEC 970 837 */ 971 838 -
pjproject/trunk/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
r3734 r3776 71 71 static pj_status_t ffmpeg_codec_get_param(pjmedia_vid_codec *codec, 72 72 pjmedia_vid_codec_param *param); 73 static pj_status_t ffmpeg_packetize ( pjmedia_vid_codec *codec, 74 pj_uint8_t *buf, 75 pj_size_t buf_len, 76 unsigned *pos, 77 const pj_uint8_t **payload, 78 pj_size_t *payload_len); 79 static pj_status_t ffmpeg_unpacketize(pjmedia_vid_codec *codec, 80 const pj_uint8_t *payload, 81 pj_size_t payload_len, 82 pj_uint8_t *buf, 83 pj_size_t buf_len, 84 unsigned *pos); 85 static pj_status_t ffmpeg_codec_encode( pjmedia_vid_codec *codec, 86 const pjmedia_frame *input, 87 unsigned output_buf_len, 88 pjmedia_frame *output); 89 static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec, 90 const pjmedia_frame *input, 91 unsigned output_buf_len, 92 pjmedia_frame *output); 73 static pj_status_t ffmpeg_codec_encode_begin( pjmedia_vid_codec *codec, 74 const pjmedia_frame *input, 75 unsigned out_size, 76 pjmedia_frame *output, 77 pj_bool_t *has_more); 78 static pj_status_t ffmpeg_codec_encode_more(pjmedia_vid_codec *codec, 79 unsigned out_size, 80 pjmedia_frame *output, 81 pj_bool_t *has_more); 82 static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec, 83 pj_size_t pkt_count, 84 pjmedia_frame packets[], 85 unsigned out_size, 86 pjmedia_frame *output); 93 87 94 88 /* Definition for FFMPEG codecs operations. */ … … 100 94 &ffmpeg_codec_modify, 101 95 &ffmpeg_codec_get_param, 102 &ffmpeg_packetize, 103 &ffmpeg_unpacketize, 104 &ffmpeg_codec_encode, 96 &ffmpeg_codec_encode_begin, 97 &ffmpeg_codec_encode_more, 105 98 &ffmpeg_codec_decode, 106 99 NULL … … 145 138 const pjmedia_video_format_info *dec_vfi; 146 139 pjmedia_video_apply_fmt_param dec_vafp; 140 141 /* Buffers, only needed for multi-packets */ 142 pj_bool_t whole; 143 void *enc_buf; 144 unsigned enc_buf_size; 145 unsigned enc_frame_len; 146 unsigned enc_processed; 147 void *dec_buf; 148 unsigned dec_buf_size; 147 149 148 150 /* The ffmpeg codec states. */ … … 236 238 237 239 /* Internal codec info */ 238 ffmpeg_codec_desc codec_desc[] =240 static ffmpeg_codec_desc codec_desc[] = 239 241 { 240 242 #if ENABLE_H264 … … 478 480 (desc->info.fmt_id == info->fmt_id) && 479 481 ((desc->info.dir & info->dir) == info->dir) && 480 (desc->info.pt == info->pt)) 482 (desc->info.pt == info->pt) && 483 (desc->info.packings & info->packings)) 481 484 { 482 485 return desc; … … 540 543 541 544 /* Enum FFMPEG codecs */ 542 for (c=av_codec_next(NULL); c; c=av_codec_next(c)) 543 { 545 for (c=av_codec_next(NULL); c; c=av_codec_next(c)) { 544 546 ffmpeg_codec_desc *desc; 545 547 pjmedia_format_id fmt_id; … … 659 661 desc->info.clock_rate = 90000; 660 662 661 /* Set RTP packetization support flag in the codec info */ 662 desc->info.has_rtp_pack = (desc->packetize != NULL) && 663 (desc->unpacketize != NULL); 663 /* Set supported packings */ 664 desc->info.packings |= PJMEDIA_VID_PACKING_WHOLE; 665 if (desc->packetize && desc->unpacketize) 666 desc->info.packings |= PJMEDIA_VID_PACKING_PACKETS; 667 664 668 } 665 669 … … 707 711 desc->info.dir |= copied_dir; 708 712 desc->enabled = (desc->info.dir != PJMEDIA_DIR_NONE); 709 desc->info.has_rtp_pack = (desc->packetize != NULL) && 710 (desc->unpacketize != NULL); 713 714 /* Set supported packings */ 715 desc->info.packings |= PJMEDIA_VID_PACKING_WHOLE; 716 if (desc->packetize && desc->unpacketize) 717 desc->info.packings |= PJMEDIA_VID_PACKING_PACKETS; 711 718 712 719 if (copied_dir != PJMEDIA_DIR_NONE) { … … 802 809 { 803 810 const ffmpeg_codec_desc *desc; 811 unsigned i; 804 812 805 813 PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL); … … 812 820 813 821 pj_bzero(attr, sizeof(pjmedia_vid_codec_param)); 822 823 /* Scan the requested packings and use the lowest number */ 824 attr->packing = 0; 825 for (i=0; i<15; ++i) { 826 unsigned packing = (1 << i); 827 if ((desc->info.packings & info->packings) & packing) { 828 attr->packing = (pjmedia_vid_packing)packing; 829 break; 830 } 831 } 832 if (attr->packing == 0) { 833 /* No supported packing in info */ 834 return PJMEDIA_CODEC_EUNSUP; 835 } 814 836 815 837 /* Direction */ … … 1153 1175 } 1154 1176 1177 /* Alloc buffers if needed */ 1178 ff->whole = (ff->param.packing == PJMEDIA_VID_PACKING_WHOLE); 1179 if (!ff->whole) { 1180 ff->enc_buf_size = ff->enc_vafp.framebytes; 1181 ff->enc_buf = pj_pool_alloc(ff->pool, ff->enc_buf_size); 1182 1183 ff->dec_buf_size = ff->dec_vafp.framebytes; 1184 ff->dec_buf = pj_pool_alloc(ff->pool, ff->dec_buf_size); 1185 } 1186 1155 1187 /* Update codec attributes, e.g: encoding format may be changed by 1156 1188 * SDP fmtp negotiation. … … 1260 1292 * Encode frames. 1261 1293 */ 1262 static pj_status_t ffmpeg_codec_encode ( pjmedia_vid_codec *codec,1263 1264 unsigned output_buf_len,1265 1294 static pj_status_t ffmpeg_codec_encode_whole(pjmedia_vid_codec *codec, 1295 const pjmedia_frame *input, 1296 unsigned output_buf_len, 1297 pjmedia_frame *output) 1266 1298 { 1267 1299 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; … … 1312 1344 } 1313 1345 1346 static pj_status_t ffmpeg_codec_encode_begin( pjmedia_vid_codec *codec, 1347 const pjmedia_frame *input, 1348 unsigned out_size, 1349 pjmedia_frame *output, 1350 pj_bool_t *has_more) 1351 { 1352 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 1353 pj_status_t status; 1354 1355 *has_more = PJ_FALSE; 1356 1357 if (ff->whole) { 1358 status = ffmpeg_codec_encode_whole(codec, input, out_size, output); 1359 } else { 1360 pjmedia_frame whole_frm; 1361 const pj_uint8_t *payload; 1362 pj_size_t payload_len; 1363 1364 pj_bzero(&whole_frm, sizeof(whole_frm)); 1365 whole_frm.buf = ff->enc_buf; 1366 whole_frm.size = ff->enc_buf_size; 1367 status = ffmpeg_codec_encode_whole(codec, input, 1368 whole_frm.size, &whole_frm); 1369 if (status != PJ_SUCCESS) 1370 return status; 1371 1372 ff->enc_frame_len = (unsigned)whole_frm.size; 1373 ff->enc_processed = 0; 1374 status = ffmpeg_packetize(codec, (pj_uint8_t*)whole_frm.buf, 1375 whole_frm.size, &ff->enc_processed, 1376 &payload, &payload_len); 1377 if (status != PJ_SUCCESS) 1378 return status; 1379 1380 if (out_size < payload_len) 1381 return PJMEDIA_CODEC_EFRMTOOSHORT; 1382 1383 output->type = PJMEDIA_FRAME_TYPE_VIDEO; 1384 pj_memcpy(output->buf, payload, payload_len); 1385 output->size = payload_len; 1386 1387 *has_more = (ff->enc_processed < ff->enc_frame_len); 1388 } 1389 1390 return status; 1391 } 1392 1393 static pj_status_t ffmpeg_codec_encode_more(pjmedia_vid_codec *codec, 1394 unsigned out_size, 1395 pjmedia_frame *output, 1396 pj_bool_t *has_more) 1397 { 1398 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 1399 const pj_uint8_t *payload; 1400 pj_size_t payload_len; 1401 pj_status_t status; 1402 1403 *has_more = PJ_FALSE; 1404 1405 if (ff->enc_processed >= ff->enc_frame_len) { 1406 /* No more frame */ 1407 return PJ_EEOF; 1408 } 1409 1410 status = ffmpeg_packetize(codec, (pj_uint8_t*)ff->enc_buf, 1411 ff->enc_frame_len, &ff->enc_processed, 1412 &payload, &payload_len); 1413 if (status != PJ_SUCCESS) 1414 return status; 1415 1416 if (out_size < payload_len) 1417 return PJMEDIA_CODEC_EFRMTOOSHORT; 1418 1419 output->type = PJMEDIA_FRAME_TYPE_VIDEO; 1420 pj_memcpy(output->buf, payload, payload_len); 1421 output->size = payload_len; 1422 1423 *has_more = (ff->enc_processed < ff->enc_frame_len); 1424 1425 return PJ_SUCCESS; 1426 } 1427 1428 1314 1429 /* 1315 1430 * Decode frame. 1316 1431 */ 1317 static pj_status_t ffmpeg_codec_decode ( pjmedia_vid_codec *codec,1318 1319 unsigned output_buf_len,1320 1432 static pj_status_t ffmpeg_codec_decode_whole(pjmedia_vid_codec *codec, 1433 const pjmedia_frame *input, 1434 unsigned output_buf_len, 1435 pjmedia_frame *output) 1321 1436 { 1322 1437 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; … … 1417 1532 return status; 1418 1533 1534 /* Realloc buffer if necessary */ 1535 if (ff->dec_vafp.framebytes > ff->dec_buf_size) { 1536 PJ_LOG(5,(THIS_FILE, "Reallocating decoding buffer %u --> %u", 1537 (unsigned)ff->dec_buf_size, 1538 (unsigned)ff->dec_vafp.framebytes)); 1539 ff->dec_buf_size = ff->dec_vafp.framebytes; 1540 ff->dec_buf = pj_pool_alloc(ff->pool, ff->dec_buf_size); 1541 } 1542 1419 1543 /* Broadcast event */ 1420 1544 if (pjmedia_event_publisher_has_sub(&codec->epub)) { … … 1476 1600 } 1477 1601 1602 static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec, 1603 pj_size_t pkt_count, 1604 pjmedia_frame packets[], 1605 unsigned out_size, 1606 pjmedia_frame *output) 1607 { 1608 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 1609 pj_status_t status; 1610 1611 PJ_ASSERT_RETURN(codec && pkt_count > 0 && packets && output, 1612 PJ_EINVAL); 1613 1614 if (ff->whole) { 1615 pj_assert(pkt_count==1); 1616 return ffmpeg_codec_decode_whole(codec, &packets[0], out_size, output); 1617 } else { 1618 pjmedia_frame whole_frm; 1619 unsigned whole_len = 0; 1620 unsigned i; 1621 1622 for (i=0; i<pkt_count; ++i) { 1623 if (whole_len + packets[i].size > ff->dec_buf_size) { 1624 PJ_LOG(5,(THIS_FILE, "Decoding buffer overflow")); 1625 break; 1626 } 1627 1628 status = ffmpeg_unpacketize(codec, packets[i].buf, packets[i].size, 1629 ff->dec_buf, ff->dec_buf_size, 1630 &whole_len); 1631 if (status != PJ_SUCCESS) { 1632 PJ_PERROR(5,(THIS_FILE, status, "Unpacketize error")); 1633 continue; 1634 } 1635 } 1636 1637 whole_frm.buf = ff->dec_buf; 1638 whole_frm.size = whole_len; 1639 whole_frm.timestamp = output->timestamp = packets[i].timestamp; 1640 whole_frm.bit_info = 0; 1641 1642 return ffmpeg_codec_decode_whole(codec, &whole_frm, out_size, output); 1643 } 1644 } 1645 1478 1646 1479 1647 #ifdef _MSC_VER -
pjproject/trunk/pjmedia/src/pjmedia/endpoint.c
r3667 r3776 585 585 586 586 /* Must support RTP packetization and bidirectional */ 587 if ( !codec_info[i].has_rtp_pack||587 if ((codec_info[i].packings & PJMEDIA_VID_PACKING_PACKETS) == 0 || 588 588 codec_info[i].dir != PJMEDIA_DIR_ENCODING_DECODING) 589 589 { -
pjproject/trunk/pjmedia/src/pjmedia/vid_stream.c
r3667 r3776 124 124 unsigned frame_ts_len; /**< Frame length in timestamp. */ 125 125 126 unsigned rx_frame_cnt; /**< # of array in rx_frames */ 127 pjmedia_frame *rx_frames; /**< Temp. buffer for incoming 128 frame assembly. */ 129 126 130 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0 127 131 pj_bool_t use_ka; /**< Stream keep-alive with non- … … 732 736 void *rtphdr; 733 737 int rtphdrlen; 734 unsigned processed = 0; 738 pj_bool_t has_more_data = PJ_FALSE; 739 pj_size_t total_sent = 0; 735 740 736 741 … … 767 772 768 773 /* Encode! */ 769 status = pjmedia_vid_codec_encode(stream->codec, frame, 770 channel->buf_size - 771 sizeof(pjmedia_rtp_hdr), 772 &frame_out); 774 status = pjmedia_vid_codec_encode_begin(stream->codec, frame, 775 channel->buf_size - 776 sizeof(pjmedia_rtp_hdr), 777 &frame_out, 778 &has_more_data); 773 779 if (status != PJ_SUCCESS) { 774 LOGERR_((channel->port.info.name.ptr, 775 "Codec encode() error", status));780 LOGERR_((channel->port.info.name.ptr, 781 "Codec encode_begin() error", status)); 776 782 777 783 /* Update RTP timestamp */ 778 784 pjmedia_rtp_encode_rtp(&channel->rtp, channel->pt, 1, 0, 779 rtp_ts_len, (const void**)&rtphdr, &rtphdrlen); 780 return status; 781 } 782 783 784 while (processed < frame_out.size) { 785 pj_uint8_t *payload; 786 pj_uint8_t *rtp_pkt; 787 pj_size_t payload_len; 788 789 /* Generate RTP payload */ 790 status = pjmedia_vid_codec_packetize(stream->codec, 791 (pj_uint8_t*)frame_out.buf, 792 frame_out.size, 793 &processed, 794 (const pj_uint8_t**)&payload, 795 &payload_len); 796 if (status != PJ_SUCCESS) { 797 LOGERR_((channel->port.info.name.ptr, 798 "Codec pack() error", status)); 799 800 /* Update RTP timestamp */ 801 pjmedia_rtp_encode_rtp(&channel->rtp, channel->pt, 1, 0, 802 rtp_ts_len, (const void**)&rtphdr, 803 &rtphdrlen); 804 return status; 805 } 806 807 /* Encapsulate. */ 808 status = pjmedia_rtp_encode_rtp( &channel->rtp, 809 channel->pt, 810 (processed==frame_out.size?1:0), 811 payload_len, 812 rtp_ts_len, 813 (const void**)&rtphdr, 814 &rtphdrlen); 815 816 if (status != PJ_SUCCESS) { 817 LOGERR_((channel->port.info.name.ptr, 785 rtp_ts_len, (const void**)&rtphdr, 786 &rtphdrlen); 787 return status; 788 } 789 790 /* Loop while we have frame to send */ 791 for (;;) { 792 status = pjmedia_rtp_encode_rtp(&channel->rtp, 793 channel->pt, 794 (has_more_data == PJ_FALSE ? 1 : 0), 795 frame_out.size, 796 rtp_ts_len, 797 (const void**)&rtphdr, 798 &rtphdrlen); 799 if (status != PJ_SUCCESS) { 800 LOGERR_((channel->port.info.name.ptr, 818 801 "RTP encode_rtp() error", status)); 819 802 return status; 820 } 821 822 /* Next packets use same timestamp */ 823 rtp_ts_len = 0; 824 825 rtp_pkt = payload - sizeof(pjmedia_rtp_hdr); 826 827 /* Copy RTP header to the beginning of packet */ 828 pj_memcpy(rtp_pkt, rtphdr, sizeof(pjmedia_rtp_hdr)); 829 830 /* Send the RTP packet to the transport. */ 831 pjmedia_transport_send_rtp(stream->transport, rtp_pkt, 832 payload_len + sizeof(pjmedia_rtp_hdr)); 803 } 804 805 // Copy RTP header to the beginning of packet 806 pj_memcpy(channel->buf, rtphdr, sizeof(pjmedia_rtp_hdr)); 807 808 // Send the RTP packet to the transport. 809 status = pjmedia_transport_send_rtp(stream->transport, 810 (char*)channel->buf, 811 frame_out.size + 812 sizeof(pjmedia_rtp_hdr)); 813 if (status != PJ_SUCCESS) { 814 LOGERR_((channel->port.info.name.ptr, 815 "Transport send_rtp() error", status)); 816 /* Ignore this error */ 817 } 818 819 total_sent += frame_out.size; 820 821 if (!has_more_data) 822 break; 823 824 /* Next packets use same timestamp */ 825 rtp_ts_len = 0; 826 827 frame_out.size = 0; 828 829 /* Encode more! */ 830 status = pjmedia_vid_codec_encode_more(stream->codec, 831 channel->buf_size - 832 sizeof(pjmedia_rtp_hdr), 833 &frame_out, 834 &has_more_data); 835 if (status != PJ_SUCCESS) { 836 LOGERR_((channel->port.info.name.ptr, 837 "Codec encode_more() error", status)); 838 /* Ignore this error (?) */ 839 break; 840 } 833 841 } 834 842 … … 842 850 843 851 /* Do nothing if we have nothing to transmit */ 844 if ( frame_out.size== 0) {852 if (total_sent == 0) { 845 853 return PJ_SUCCESS; 846 854 } 847 855 848 856 /* Update stat */ 849 pjmedia_rtcp_tx_rtp(&stream->rtcp, frame_out.size);857 pjmedia_rtcp_tx_rtp(&stream->rtcp, total_sent); 850 858 stream->rtcp.stat.rtp_tx_last_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts); 851 859 stream->rtcp.stat.rtp_tx_last_seq = pj_ntohs(stream->enc->rtp.out_hdr.seq); … … 864 872 pjmedia_vid_stream *stream = (pjmedia_vid_stream*) port->port_data.pdata; 865 873 pjmedia_vid_channel *channel = stream->dec; 866 pjmedia_frame frame_in;867 874 pj_uint32_t last_ts = 0; 868 875 int frm_first_seq = 0, frm_last_seq = 0; 876 pj_bool_t got_frame = PJ_FALSE; 877 unsigned cnt; 869 878 pj_status_t status; 870 879 … … 876 885 877 886 /* Repeat get payload from the jitter buffer until all payloads with same 878 * timestamp are collected (a complete frame unpacketized).887 * timestamp are collected. 879 888 */ 880 { 881 pj_bool_t got_frame; 882 unsigned cnt; 883 884 channel->buf_len = 0; 885 got_frame = PJ_FALSE; 886 887 /* Lock jitter buffer mutex first */ 888 pj_mutex_lock( stream->jb_mutex ); 889 890 /* Check if we got a decodable frame */ 891 for (cnt=0; ; ++cnt) { 892 char ptype; 893 pj_uint32_t ts; 894 int seq; 895 896 /* Peek frame from jitter buffer. */ 897 pjmedia_jbuf_peek_frame(stream->jb, cnt, NULL, NULL, 898 &ptype, NULL, &ts, &seq); 899 if (ptype == PJMEDIA_JB_NORMAL_FRAME) { 900 if (last_ts == 0) { 901 last_ts = ts; 902 frm_first_seq = seq; 903 } 904 if (ts != last_ts) { 905 got_frame = PJ_TRUE; 906 break; 907 } 908 frm_last_seq = seq; 909 } else if (ptype == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 910 /* No more packet in the jitter buffer */ 889 channel->buf_len = 0; 890 891 /* Lock jitter buffer mutex first */ 892 pj_mutex_lock( stream->jb_mutex ); 893 894 /* Check if we got a decodable frame */ 895 for (cnt=0; ; ++cnt) { 896 char ptype; 897 pj_uint32_t ts; 898 int seq; 899 900 /* Peek frame from jitter buffer. */ 901 pjmedia_jbuf_peek_frame(stream->jb, cnt, NULL, NULL, 902 &ptype, NULL, &ts, &seq); 903 if (ptype == PJMEDIA_JB_NORMAL_FRAME) { 904 if (last_ts == 0) { 905 last_ts = ts; 906 frm_first_seq = seq; 907 } 908 if (ts != last_ts) { 909 got_frame = PJ_TRUE; 911 910 break; 912 911 } 912 frm_last_seq = seq; 913 } else if (ptype == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 914 /* No more packet in the jitter buffer */ 915 break; 913 916 } 914 915 if (got_frame) { 916 unsigned i; 917 918 /* Generate frame bitstream from the payload */ 919 channel->buf_len = 0; 920 for (i = 0; i < cnt; ++i) { 921 const pj_uint8_t *p; 922 pj_size_t psize; 923 char ptype; 924 925 /* We use jbuf_peek_frame() as it will returns the pointer of 926 * the payload (no buffer and memcpy needed), just as we need. 927 */ 928 pjmedia_jbuf_peek_frame(stream->jb, i, (const void**)&p, 929 &psize, &ptype, NULL, NULL, NULL); 930 931 if (ptype != PJMEDIA_JB_NORMAL_FRAME) { 932 /* Packet lost, must set payload to NULL and keep going */ 933 p = NULL; 934 psize = 0; 935 } 936 937 status = pjmedia_vid_codec_unpacketize( 938 stream->codec, 939 p, psize, 940 (pj_uint8_t*)channel->buf, 941 channel->buf_size, 942 &channel->buf_len); 943 if (status != PJ_SUCCESS) { 944 LOGERR_((channel->port.info.name.ptr, 945 "Codec unpack() error", status)); 946 /* Just ignore this unpack error */ 947 } 917 } 918 919 if (got_frame) { 920 unsigned i; 921 922 /* Generate frame bitstream from the payload */ 923 channel->buf_len = 0; 924 925 if (cnt > stream->rx_frame_cnt) { 926 PJ_LOG(1,(port->info.name.ptr, 927 "Discarding %u frames because array is full!", 928 cnt - stream->rx_frame_cnt)); 929 pjmedia_jbuf_remove_frame(stream->jb, cnt - stream->rx_frame_cnt); 930 cnt = stream->rx_frame_cnt; 931 } 932 933 for (i = 0; i < cnt; ++i) { 934 char ptype; 935 936 stream->rx_frames[i].type = PJMEDIA_FRAME_TYPE_VIDEO; 937 stream->rx_frames[i].timestamp.u64 = last_ts; 938 stream->rx_frames[i].bit_info = 0; 939 940 /* We use jbuf_peek_frame() as it will returns the pointer of 941 * the payload (no buffer and memcpy needed), just as we need. 942 */ 943 pjmedia_jbuf_peek_frame(stream->jb, i, 944 (const void**)&stream->rx_frames[i].buf, 945 &stream->rx_frames[i].size, &ptype, 946 NULL, NULL, NULL); 947 948 if (ptype != PJMEDIA_JB_NORMAL_FRAME) { 949 /* Packet lost, must set payload to NULL and keep going */ 950 stream->rx_frames[i].buf = NULL; 951 stream->rx_frames[i].size = 0; 952 stream->rx_frames[i].type = PJMEDIA_FRAME_TYPE_NONE; 953 continue; 948 954 } 949 950 pjmedia_jbuf_remove_frame(stream->jb, cnt);951 955 } 952 956 953 /* Unlock jitter buffer mutex. */ 954 pj_mutex_unlock( stream->jb_mutex ); 955 956 if (!got_frame) { 957 /* Decode */ 958 status = pjmedia_vid_codec_decode(stream->codec, cnt, 959 stream->rx_frames, 960 frame->size, frame); 961 if (status != PJ_SUCCESS) { 962 LOGERR_((port->info.name.ptr, "codec decode() error", 963 status)); 957 964 frame->type = PJMEDIA_FRAME_TYPE_NONE; 958 965 frame->size = 0; 959 return PJ_SUCCESS;960 966 } 961 } 962 963 /* Decode */ 964 frame_in.buf = channel->buf; 965 frame_in.size = channel->buf_len; 966 frame_in.bit_info = 0; 967 frame_in.type = PJMEDIA_FRAME_TYPE_VIDEO; 968 frame_in.timestamp.u64 = last_ts; 969 970 status = pjmedia_vid_codec_decode(stream->codec, &frame_in, 971 frame->size, frame); 972 if (status != PJ_SUCCESS) { 973 LOGERR_((port->info.name.ptr, "codec decode() error", 974 status)); 975 frame->type = PJMEDIA_FRAME_TYPE_NONE; 976 frame->size = 0; 977 } 967 968 pjmedia_jbuf_remove_frame(stream->jb, cnt); 969 } 970 971 /* Unlock jitter buffer mutex. */ 972 pj_mutex_unlock( stream->jb_mutex ); 978 973 979 974 /* Learn remote frame rate after successful decoding */ … … 1014 1009 1015 1010 pjmedia_event_init(&event, PJMEDIA_EVENT_FMT_CHANGED, 1016 &frame _in.timestamp, &stream->epub);1011 &frame->timestamp, &stream->epub); 1017 1012 event.data.fmt_changed.dir = PJMEDIA_DIR_DECODING; 1018 1013 pj_memcpy(&event.data.fmt_changed.new_fmt, … … 1157 1152 pjmedia_video_format_detail *vfd_enc; 1158 1153 char *p; 1154 unsigned mtu; 1159 1155 pj_status_t status; 1160 1156 … … 1188 1184 return status; 1189 1185 1190 1191 1186 /* Get codec param: */ 1192 1187 if (!info->codec_param) { … … 1202 1197 pj_assert(info->codec_param); 1203 1198 } 1199 1200 /* Init codec param and adjust MTU */ 1201 info->codec_param->dir = info->dir; 1202 info->codec_param->enc_mtu -= (sizeof(pjmedia_rtp_hdr) + 1203 PJMEDIA_STREAM_RESV_PAYLOAD_LEN); 1204 if (info->codec_param->enc_mtu > PJMEDIA_MAX_MTU) 1205 info->codec_param->enc_mtu = PJMEDIA_MAX_MTU; 1206 mtu = info->codec_param->enc_mtu; 1204 1207 1205 1208 vfd_enc = pjmedia_format_get_video_format_detail( … … 1235 1238 if (status != PJ_SUCCESS) 1236 1239 return status; 1237 1238 /* Init codec param */1239 info->codec_param->dir = info->dir;1240 info->codec_param->enc_mtu = PJMEDIA_MAX_MTU - sizeof(pjmedia_rtp_hdr) -1241 PJMEDIA_STREAM_RESV_PAYLOAD_LEN;1242 1240 1243 1241 /* Init and open the codec. */ … … 1295 1293 /* Init jitter buffer parameters: */ 1296 1294 frm_ptime = 1000 * vfd_enc->fps.denum / vfd_enc->fps.num; 1297 chunks_per_frm = stream->frame_size / PJMEDIA_MAX_MTU; 1295 chunks_per_frm = stream->frame_size / mtu; 1296 if (chunks_per_frm == 0) chunks_per_frm = 1; 1298 1297 1299 1298 /* JB max count, default 500ms */ … … 1321 1320 jb_init = 0; 1322 1321 1322 /* Allocate array for temporary storage for assembly of incoming 1323 * frames. Add more just in case. 1324 */ 1325 stream->rx_frame_cnt = chunks_per_frm * 2; 1326 stream->rx_frames = pj_pool_calloc(pool, stream->rx_frame_cnt, 1327 sizeof(stream->rx_frames[0])); 1328 1323 1329 /* Create jitter buffer */ 1324 1330 status = pjmedia_jbuf_create(pool, &stream->dec->port.info.name, 1325 PJMEDIA_MAX_MTU, 1331 mtu + PJMEDIA_STREAM_RESV_PAYLOAD_LEN, 1326 1332 1000 * vfd_enc->fps.denum / vfd_enc->fps.num, 1327 1333 jb_max, &stream->jb); … … 1461 1467 1462 1468 /* Destroy jitter buffer */ 1463 if (stream->jb) 1469 if (stream->jb) { 1464 1470 pjmedia_jbuf_destroy(stream->jb); 1471 stream->jb = NULL; 1472 } 1465 1473 1466 1474 #if TRACE_JB … … 1708 1716 } 1709 1717 1710 1718 1719 /* Request for codec with the correct packing for streaming */ 1720 si->codec_info.packings = PJMEDIA_VID_PACKING_PACKETS; 1721 1711 1722 /* Now that we have codec info, get the codec param. */ 1712 1723 si->codec_param = PJ_POOL_ALLOC_T(pool, pjmedia_vid_codec_param); -
pjproject/trunk/pjmedia/src/test/vid_codec_test.c
r3715 r3776 29 29 #define THIS_FILE "vid_codec.c" 30 30 31 #define BYPASS_CODEC 032 #define BYPASS_PACKETIZER 033 34 31 /* 35 32 * Capture device setting: … … 81 78 pjmedia_frame *frame) 82 79 { 80 enum { MAX_PACKETS = 50 }; 83 81 codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata; 84 82 pj_status_t status; 85 86 #if !BYPASS_CODEC 87 { 88 pjmedia_vid_codec *codec = port_data->codec; 89 pjmedia_frame enc_frame; 90 91 enc_frame.buf = port_data->enc_buf; 92 enc_frame.size = port_data->enc_buf_size; 93 94 status = pjmedia_vid_codec_encode(codec, frame, enc_frame.size, 95 &enc_frame); 96 if (status != PJ_SUCCESS) goto on_error; 97 98 #if !BYPASS_PACKETIZER 99 if (enc_frame.size) { 100 unsigned pos = 0; 101 pj_bool_t packetized = PJ_FALSE; 102 unsigned unpack_pos = 0; 103 104 while (pos < enc_frame.size) { 105 pj_uint8_t *payload; 106 pj_size_t payload_len; 107 108 status = pjmedia_vid_codec_packetize( 109 codec, 110 (pj_uint8_t*)enc_frame.buf, 111 enc_frame.size, &pos, 112 (const pj_uint8_t**)&payload, 113 &payload_len); 114 if (status == PJ_ENOTSUP) 115 break; 116 if (status != PJ_SUCCESS) 117 goto on_error; 118 119 status = pjmedia_vid_codec_unpacketize( 120 codec, payload, payload_len, 121 port_data->pack_buf, 122 port_data->pack_buf_size, 123 &unpack_pos); 124 if (status != PJ_SUCCESS) 125 goto on_error; 126 127 // what happen if the bitstream is broken? 128 //if (i++ != 1) unpack_pos -= 10; 129 130 packetized = PJ_TRUE; 131 } 132 133 if (packetized) { 134 enc_frame.buf = port_data->pack_buf; 135 enc_frame.size = unpack_pos; 136 } 83 pjmedia_vid_codec *codec = port_data->codec; 84 unsigned enc_cnt = 0; 85 pj_uint8_t *enc_buf; 86 unsigned enc_size_left; 87 pjmedia_frame enc_frames[MAX_PACKETS]; 88 pj_bool_t has_more = PJ_FALSE; 89 90 enc_buf = port_data->enc_buf; 91 enc_size_left = port_data->enc_buf_size; 92 93 /* 94 * Encode 95 */ 96 enc_frames[enc_cnt].buf = enc_buf; 97 enc_frames[enc_cnt].size = enc_size_left; 98 99 status = pjmedia_vid_codec_encode_begin(codec, frame, enc_size_left, 100 &enc_frames[enc_cnt], &has_more); 101 if (status != PJ_SUCCESS) goto on_error; 102 103 enc_buf += enc_frames[enc_cnt].size; 104 enc_size_left -= enc_frames[enc_cnt].size; 105 106 ++enc_cnt; 107 while (has_more) { 108 enc_frames[enc_cnt].buf = enc_buf; 109 enc_frames[enc_cnt].size = enc_size_left; 110 111 status = pjmedia_vid_codec_encode_more(codec, enc_size_left, 112 &enc_frames[enc_cnt], 113 &has_more); 114 if (status != PJ_SUCCESS) 115 break; 116 117 enc_buf += enc_frames[enc_cnt].size; 118 enc_size_left -= enc_frames[enc_cnt].size; 119 120 ++enc_cnt; 121 122 if (enc_cnt >= MAX_PACKETS) { 123 assert(!"Too many packets!"); 124 break; 137 125 } 138 #endif 139 140 status = pjmedia_vid_codec_decode(codec, &enc_frame, 141 frame->size, frame); 142 if (status != PJ_SUCCESS) goto on_error; 143 } 144 #endif 145 126 } 127 128 /* 129 * Decode 130 */ 131 status = pjmedia_vid_codec_decode(codec, enc_cnt, enc_frames, 132 frame->size, frame); 133 if (status != PJ_SUCCESS) goto on_error; 134 135 /* Display */ 146 136 status = pjmedia_port_put_frame( 147 137 pjmedia_vid_port_get_passive_port(port_data->rdr_port), … … 196 186 } 197 187 198 static int encode_decode_test(pj_pool_t *pool, const char *codec_id) 188 static int encode_decode_test(pj_pool_t *pool, const char *codec_id, 189 pjmedia_vid_packing packing) 199 190 { 200 191 const pj_str_t port_name = {"codec", 5}; … … 205 196 pjmedia_vid_codec_param codec_param; 206 197 const pjmedia_vid_codec_info *codec_info; 207 198 const char *packing_name; 208 199 pjmedia_vid_dev_index cap_idx, rdr_idx; 209 200 pjmedia_vid_port *capture=NULL, *renderer=NULL; … … 211 202 pjmedia_video_format_detail *vfd; 212 203 pjmedia_event_subscription esub; 204 char codec_name[5]; 213 205 pj_status_t status; 214 206 int rc = 0; 215 207 216 PJ_LOG(3, (THIS_FILE, " encode decode test")); 208 switch (packing) { 209 case PJMEDIA_VID_PACKING_PACKETS: 210 packing_name = "framed"; 211 break; 212 case PJMEDIA_VID_PACKING_WHOLE: 213 packing_name = "whole"; 214 break; 215 default: 216 packing_name = "unknown"; 217 break; 218 } 219 220 PJ_LOG(3, (THIS_FILE, " encode decode test: codec=%s, packing=%s", 221 codec_id, packing_name)); 217 222 218 223 /* Lookup codec */ … … 294 299 } 295 300 296 #if !BYPASS_CODEC 301 codec_param.packing = packing; 297 302 298 303 /* Open codec */ … … 322 327 &codec_port_data); 323 328 pjmedia_event_subscribe(&codec->epub, &esub); 324 #endif /* !BYPASS_CODEC */325 329 } 326 330 … … 393 397 } 394 398 395 #if BYPASS_CODEC 396 PJ_LOG(3, (THIS_FILE, " starting loopback test: %c%c%c%c %dx%d", 397 ((codec_param.dec_fmt.id & 0x000000FF) >> 0), 398 ((codec_param.dec_fmt.id & 0x0000FF00) >> 8), 399 ((codec_param.dec_fmt.id & 0x00FF0000) >> 16), 400 ((codec_param.dec_fmt.id & 0xFF000000) >> 24), 401 codec_param.dec_fmt.det.vid.size.w, 402 codec_param.dec_fmt.det.vid.size.h 403 )); 404 #else 405 PJ_LOG(3, (THIS_FILE, " starting codec test: %c%c%c%c<->%.*s %dx%d", 406 ((codec_param.dec_fmt.id & 0x000000FF) >> 0), 407 ((codec_param.dec_fmt.id & 0x0000FF00) >> 8), 408 ((codec_param.dec_fmt.id & 0x00FF0000) >> 16), 409 ((codec_param.dec_fmt.id & 0xFF000000) >> 24), 399 PJ_LOG(3, (THIS_FILE, " starting codec test: %s<->%.*s %dx%d", 400 pjmedia_fourcc_name(codec_param.dec_fmt.id, codec_name), 410 401 codec_info->encoding_name.slen, 411 402 codec_info->encoding_name.ptr, … … 413 404 codec_param.dec_fmt.det.vid.size.h 414 405 )); 415 #endif416 406 417 407 /* Start streaming.. */ … … 456 446 457 447 orig_log_level = pj_log_get_level(); 458 pj_log_set_level( 6);448 pj_log_set_level(3); 459 449 460 450 PJ_LOG(3, (THIS_FILE, "Performing video codec tests..")); … … 476 466 goto on_return; 477 467 478 rc = encode_decode_test(pool, "h263-1998"); 468 rc = encode_decode_test(pool, "h263-1998", PJMEDIA_VID_PACKING_WHOLE); 469 if (rc != 0) 470 goto on_return; 471 472 rc = encode_decode_test(pool, "h263-1998", PJMEDIA_VID_PACKING_PACKETS); 479 473 if (rc != 0) 480 474 goto on_return; -
pjproject/trunk/pjsip-apps/src/samples/aviplay.c
r3688 r3776 154 154 if (status != PJ_SUCCESS) goto on_error; 155 155 156 status = pjmedia_vid_codec_decode(codec, frame, frame->size, &enc_frame); 156 status = pjmedia_vid_codec_decode(codec, 1, frame, 157 frame->size, &enc_frame); 157 158 if (status != PJ_SUCCESS) goto on_error; 158 159 … … 167 168 if (status != PJ_SUCCESS) goto on_error; 168 169 169 status = pjmedia_vid_codec_decode(codec, &enc_frame, frame->size, frame); 170 status = pjmedia_vid_codec_decode(codec, 1, &enc_frame, 171 frame->size, frame); 170 172 if (status != PJ_SUCCESS) goto on_error; 171 173 … … 292 294 293 295 pjmedia_format_copy(&codec_param.dec_fmt, ¶m.vidparam.fmt); 294 296 codec_param.packing = PJMEDIA_VID_PACKING_WHOLE; 295 297 status = pjmedia_vid_codec_open(codec, &codec_param); 296 298 if (status != PJ_SUCCESS) { -
pjproject/trunk/pjsip-apps/src/samples/vid_streamutil.c
r3667 r3776 302 302 write_frame.buf = play_file->dec_buf; 303 303 write_frame.size = play_file->dec_buf_size; 304 status = decoder->op->decode(decoder, &read_frame, write_frame.size,305 304 status = pjmedia_vid_codec_decode(decoder, 1, &read_frame, 305 write_frame.size, &write_frame); 306 306 if (status != PJ_SUCCESS) 307 307 return; … … 616 616 pjmedia_video_format_detail *file_vfd; 617 617 pjmedia_clock_param clock_param; 618 char fmt_name[5]; 618 619 619 620 /* Create file player */ … … 625 626 file_vfd = pjmedia_format_get_video_format_detail(&play_port->info.fmt, 626 627 PJ_TRUE); 627 PJ_LOG(2, (THIS_FILE, "Reading video stream %dx%d % c%c%c%c@%.2ffps",628 PJ_LOG(2, (THIS_FILE, "Reading video stream %dx%d %s @%.2ffps", 628 629 file_vfd->size.w, file_vfd->size.h, 629 ((play_port->info.fmt.id & 0x000000FF) >> 0), 630 ((play_port->info.fmt.id & 0x0000FF00) >> 8), 631 ((play_port->info.fmt.id & 0x00FF0000) >> 16), 632 ((play_port->info.fmt.id & 0xFF000000) >> 24), 630 pjmedia_fourcc_name(play_port->info.fmt.id, fmt_name), 633 631 (1.0*file_vfd->fps.num/file_vfd->fps.denum))); 634 632 -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c
r3774 r3776 225 225 226 226 for (i=0, j=0; i<count && j<*p_count; ++i) { 227 if (info[i]. has_rtp_pack) {227 if (info[i].packings & PJMEDIA_VID_PACKING_PACKETS) { 228 228 pj_bzero(&id[j], sizeof(pjsua_codec_info)); 229 229
Note: See TracChangeset
for help on using the changeset viewer.