1 /*
2  * H.264 Plugin codec for OpenH323/OPAL
3  *
4  * Copyright (C) Matthias Schneider, All Rights Reserved
5  *
6  * This code is based on the file h261codec.cxx from the OPAL project released
7  * under the MPL 1.0 license which contains the following:
8  *
9  * Copyright (c) 1998-2000 Equivalence Pty. Ltd.
10  *
11  * The contents of this file are subject to the Mozilla Public License
12  * Version 1.0 (the "License"); you may not use this file except in
13  * compliance with the License. You may obtain a copy of the License at
14  * http://www.mozilla.org/MPL/
15  *
16  * Software distributed under the License is distributed on an "AS IS"
17  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
18  * the License for the specific language governing rights and limitations
19  * under the License.
20  *
21  * The Original Code is Open H323 Library.
22  *
23  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24  *
25  * Contributor(s): Matthias Schneider (ma30002000@yahoo.de)
26  *                 Michele Piccini (michele@piccini.com)
27  *                 Derek Smithies (derek@indranet.co.nz)
28  *                 Simon Horne (s.horne@packetizer.com)
29  *
30  *
31  */
32 
33 /*
34   Notes
35   -----
36 
37  */
38 
39 #ifndef __H264_X264_H__
40 #define __H264_X264_H__ 1
41 
42 #include "plugin-config.h"
43 
44 #include <stdarg.h>
45 
46 #ifndef _SIGNAL_ONLY
47 
48 #if defined(_WIN32) && _MSC_VER < 1600
49  #include "../common/vs-stdint.h"
50  #include "../common/critsect.h"
51 #else
52  #include <stdint.h>
53  #include "critsect.h"
54 #endif
55 
56 #include "shared/h264frame.h"
57 
58 #if defined(H323_STATIC_H264)
59 #include "h264pipe_static.h"
60 #else
61 #ifdef WIN32
62 #include "h264pipe_win32.h"
63 #else
64 #include "h264pipe_unix.h"
65 #endif
66 #endif
67 
68 #include <list>
69 
70 
71 extern "C" {
72 #ifdef _MSC_VER
73   #include "libavcodec/avcodec.h"
74 #else
75   #include LIBAVCODEC_HEADER
76 #endif
77 };
78 
79 #endif
80 
81 #define P1080_WIDTH 1920
82 #define P1080_HEIGHT 1080
83 #define P720_WIDTH 1280
84 #define P720_HEIGHT 720
85 #define CIF4_WIDTH 704
86 #define CIF4_HEIGHT 576
87 #define VGA_WIDTH 640
88 #define VGA_HEIGHT 480
89 #define CIF_WIDTH 352
90 #define CIF_HEIGHT 288
91 #define QCIF_WIDTH 176
92 #define QCIF_HEIGHT 144
93 #define SQCIF_WIDTH 128
94 #define SQCIF_HEIGHT 96
95 #define IT_QCIF 0
96 #define IT_CIF 1
97 
98 #ifndef _SIGNAL_ONLY
99 
100 typedef unsigned char u_char;
101 
102 static void logCallbackFFMPEG (void* v, int level, const char* fmt , va_list arg);
103 
104 // Input formats from the input device.
105 struct inputFormats
106 {
107   unsigned mb;
108   unsigned w;
109   unsigned h;
110   unsigned r;
111 };
112 
113     // Settings
114 static double minFPS   = 13.5;       // Minimum FPS allowed
115 static double minSpeedFPS = 20;     // Minimum speed for Emphasis Speed
116 static double kbtoMBPS = 12.2963;   // Magical Conversion factor from kb/s to MBPS
117 
118 class H264EncoderContext
119 {
120   public:
121     H264EncoderContext ();
122     ~H264EncoderContext ();
123 
124     int EncodeFrames (const u_char * src, unsigned & srcLen, u_char * dst, unsigned & dstLen, unsigned int & flags);
125 
126     void FastUpdateRequested(void);
127 
128     void SetMaxRTPFrameSize (unsigned size);
129     void SetMaxKeyFramePeriod (unsigned period);
130     void SetTargetBitrate (unsigned rate);
131     void SetFrameWidth (unsigned width);
132     void SetFrameHeight (unsigned height);
133     void SetFrameRate (unsigned rate);
134     void SetTSTO (unsigned tsto);
135     void SetProfileLevel (unsigned profile, unsigned constraints, unsigned level);
136     void SetMaxNALSize (unsigned size);
137     void SetEmphasisSpeed (bool speed);
138     void ApplyOptions ();
139     void Lock ();
140     void Unlock ();
141 
142     void AddInputFormat(inputFormats & fmt);
143     int GetInputFormat(inputFormats & fmt);
144     void ClearInputFormat();
145 
146     void SetMaxMB(unsigned mb);
147     unsigned GetMaxMB();
148     void SetMaxMBPS(unsigned mbps);
149     unsigned GetMaxMBPS();
150     bool GetEmphasisSpeed();
151 
152   protected:
153     CriticalSection _mutex;
154     H264EncCtx H264EncCtxInstance;
155 
156     unsigned maxMBPS;
157     unsigned maxMB;
158     bool emphasisSpeed;
159     std::list<inputFormats> videoInputFormats;
160 };
161 
162 class H264DecoderContext
163 {
164   public:
165     H264DecoderContext();
166     ~H264DecoderContext();
167     int DecodeFrames(const u_char * src, unsigned & srcLen, u_char * dst, unsigned & dstLen, unsigned int & flags);
168 
169   protected:
170     CriticalSection _mutex;
171 
172     AVCodec* _codec;
173     AVCodecContext* _context;
174     AVFrame* _outputFrame;
175     H264Frame* _rxH264Frame;
176 
177     bool _gotIFrame;
178     bool _gotAGoodFrame;
179 	unsigned _lastTimeStamp;
180     unsigned _lastSeqNo;
181     int _frameCounter;
182     int _frameFPUInt;
183     int _frameAutoFPU;
184     int _skippedFrameCounter;
185 };
186 
187 static int valid_for_protocol    ( const struct PluginCodec_Definition *, void *, const char *,
188                                    void * parm, unsigned * parmLen);
189 static int get_codec_options     ( const struct PluginCodec_Definition * codec, void *, const char *,
190                                    void * parm, unsigned * parmLen);
191 static int free_codec_options    ( const struct PluginCodec_Definition *, void *, const char *,
192                                    void * parm, unsigned * parmLen);
193 
194 static int to_normalised_options ( const struct PluginCodec_Definition *, void *, const char *,
195                                    void * parm, unsigned * parmLen);
196 static int to_customised_options ( const struct PluginCodec_Definition *, void *, const char *,
197                                    void * parm, unsigned * parmLen);
198 static int encoder_set_options   ( const struct PluginCodec_Definition *, void * _context, const char *,
199                                    void * parm, unsigned * parmLen);
200 static int encoder_event_handler(const struct PluginCodec_Definition * codec, void * _context, const char *,
201                                    void * parm, unsigned * parmLen);
202 static int encoder_flowcontrol   ( const struct PluginCodec_Definition *, void *, const char *,
203                                    void * parm, unsigned * parmLen);
204 static int encoder_formats       ( const struct PluginCodec_Definition *, void *, const char *,
205                                    void * parm, unsigned * parmLen);
206 static int encoder_get_output_data_size ( const PluginCodec_Definition *, void *, const char *,
207                                    void *, unsigned *);
208 static int decoder_get_output_data_size ( const PluginCodec_Definition * codec, void *, const char *,
209                                    void *, unsigned *);
210 
211 ///////////////////////////////////////////////////////////////////////////////
212 static int merge_profile_level_h264(char ** result, const char * dest, const char * src);
213 static int merge_packetization_mode(char ** result, const char * dest, const char * src);
214 static void free_string(char * str);
215 ///////////////////////////////////////////////////////////////////////////////
216 
217 #endif  // Signal Only
218 
219 static void * create_encoder     ( const struct PluginCodec_Definition *);
220 static void destroy_encoder      ( const struct PluginCodec_Definition *, void * _context);
221 static int codec_encoder         ( const struct PluginCodec_Definition *, void * _context,
222                                    const void * from, unsigned * fromLen,
223                                    void * to, unsigned * toLen,
224                                    unsigned int * flag);
225 
226 static void * create_decoder     ( const struct PluginCodec_Definition *);
227 static void destroy_decoder      ( const struct PluginCodec_Definition *, void * _context);
228 static int codec_decoder         ( const struct PluginCodec_Definition *, void * _context,
229                                    const void * from, unsigned * fromLen,
230                                    void * to, unsigned * toLen,
231                                    unsigned int * flag);
232 
233 
234 static struct PluginCodec_information licenseInfo = {
235   1143692893,                                                   // timestamp = Thu 30 Mar 2006 04:28:13 AM UTC
236 
237   "Matthias Schneider",                                         // source code author
238   "1.0",                                                        // source code version
239   "ma30002000@yahoo.de",                                        // source code email
240   "",                                                           // source code URL
241   "Copyright (C) 2006 by Matthias Schneider",                   // source code copyright
242   "MPL 1.0",                                                    // source code license
243   PluginCodec_License_MPL,                                      // source code license
244 
245   "x264 / ffmpeg H.264",                                        // codec description
246   "x264: Laurent Aimar, ffmpeg: Michael Niedermayer",           // codec author
247   "", 							        // codec version
248   "fenrir@via.ecp.fr, ffmpeg-devel-request@mplayerhq.hu",       // codec email
249   "http://developers.videolan.org/x264.html, \
250    http://ffmpeg.mplayerhq.hu", 				// codec URL
251   "x264: Copyright (C) 2003 Laurent Aimar, \
252    ffmpeg: Copyright (c) 2002-2003 Michael Niedermayer",        // codec copyright information
253   "x264: GNU General Public License as published Version 2, \
254    ffmpeg: GNU Lesser General Public License, Version 2.1",     // codec license
255   PluginCodec_License_GPL                                       // codec license code
256 };
257 
258 static const char YUV420PDesc[]  = { "YUV420P" };
259 
260 
261 
262 static PluginCodec_ControlDefn EncoderControls[] = {
263 #ifndef _SIGNAL_ONLY
264   { PLUGINCODEC_CONTROL_VALID_FOR_PROTOCOL,    valid_for_protocol },
265   { PLUGINCODEC_CONTROL_GET_CODEC_OPTIONS,     get_codec_options },
266   { PLUGINCODEC_CONTROL_FREE_CODEC_OPTIONS,    free_codec_options },
267   { PLUGINCODEC_CONTROL_TO_NORMALISED_OPTIONS, to_normalised_options },
268   { PLUGINCODEC_CONTROL_TO_CUSTOMISED_OPTIONS, to_customised_options },
269   { PLUGINCODEC_CONTROL_SET_CODEC_OPTIONS,     encoder_set_options },
270   { PLUGINCODEC_CONTROL_CODEC_EVENT,           encoder_event_handler },
271   { PLUGINCODEC_CONTROL_FLOW_OPTIONS,	       encoder_flowcontrol },
272   { PLUGINCODEC_CONTROL_SET_FORMAT_OPTIONS,    encoder_formats },
273   { PLUGINCODEC_CONTROL_GET_OUTPUT_DATA_SIZE,  encoder_get_output_data_size },
274 #endif
275   { NULL }
276 };
277 
278 static PluginCodec_ControlDefn DecoderControls[] = {
279 #ifndef _SIGNAL_ONLY
280   { PLUGINCODEC_CONTROL_GET_CODEC_OPTIONS,     get_codec_options },
281   { PLUGINCODEC_CONTROL_TO_CUSTOMISED_OPTIONS, to_customised_options },
282   { PLUGINCODEC_CONTROL_GET_OUTPUT_DATA_SIZE,  decoder_get_output_data_size },
283 #endif
284   { NULL }
285 };
286 
287 
288 /////////////////////////////////////////////////////////////////////////////
289 // SIP definitions
290 /*
291 Still to consider
292        sprop-parameter-sets: this may be a NAL
293        max-mbps, max-fs, max-cpb, max-dpb, and max-br
294        parameter-add
295        max-rcmd-nalu-size:
296 */
297 
298 static const char h264Desc[]      = { "H.264" };
299 static const char sdpH264[]       = { "h264" };
300 
301 #define H264_CLOCKRATE        90000
302 #define H264_BITRATE         768000
303 #define H264_PAYLOAD_SIZE      1400
304 #define H264_FRAME_RATE          30
305 #define H264_KEY_FRAME_INTERVAL  (30*120) // Send a key frame no more than once every two minutes (unless requested through fast update)
306 
307 
308 /////////////////////////////////////////////////////////////////////////////
309 
310 #ifndef _SIGNAL_ONLY
311 
312 static struct PluginCodec_Option const RFC3984packetizationMode =
313 {
314   PluginCodec_StringOption,             // Option type
315   "CAP RFC3894 Packetization Mode",     // User visible name
316   false,                                // User Read/Only flag
317   PluginCodec_CustomMerge,              // Merge mode
318   "1",                                  // Initial value (Baseline, Level 3)
319   "packetization-mode",                 // FMTP option name
320   "5",                                  // FMTP default value
321   0,
322   "1",
323   "5",
324   merge_packetization_mode,             // Function to do merge
325   free_string                           // Function to free memory in string
326 };
327 
328 static struct PluginCodec_Option const RFC3984profileLevel =
329 {
330   PluginCodec_StringOption,             // Option type
331   "CAP RFC3894 Profile Level",          // User visible name
332   false,                                // User Read/Only flag
333   PluginCodec_CustomMerge,              // Merge mode
334   "42C01E",                             // Initial value (Baseline, Level 3)
335   "profile-level-id",                   // FMTP option name
336   "000000",                             // FMTP default value
337   0,
338   "000000",
339   "58F033",
340   merge_profile_level_h264,             // Function to do merge
341   free_string                           // Function to free memory in string
342 };
343 
344 #endif //_SIGNAL_ONLY
345 
346 static struct PluginCodec_Option const * const optionTable[] = {
347 #ifndef _SIGNAL_ONLY
348   &RFC3984packetizationMode,
349   &RFC3984profileLevel,
350 #endif
351   NULL
352 };
353 
354 
355 ///////////////////////////////////////////////////////////////////////////
356 // H.323 Definitions
357 
358 /////////////////////////////////////////////////////////////////////////////
359 // Codec Definitions
360 
361 // SIP 42E015 is
362 //  Profile : H264_PROFILE_BASE + H264_PROFILE_MAIN
363 //  Level : 2:1  compatible H.323 codec is 4CIF.
364 #define H264_PROFILE_BASE      64   // only do base and main at this stage
365 #define H264_PROFILE_MAIN      32
366 #define H264_PROFILE_EXTENDED  16
367 #define H264_PROFILE_HIGH       8
368 
369 #define H264_BASE_IDC		   66   // RFC3984  Baseline
370 #define H264_HIGH_IDC		  100   // RFC3984  High
371 #define PLUGINCODEC_OPTION_PROFILE			"Generic Parameter 41"
372 #define PLUGINCODEC_OPTION_LEVEL			"Generic Parameter 42"
373 #define PLUGINCODEC_OPTION_ASPECT			"Generic Parameter 10"
374 #define PLUGINCODEC_OPTION_MAXFRAMERATE	    "Generic Parameter 13"
375 #define PLUGINCODEC_OPTION_CUSMBPS			"Generic Parameter 3"
376 #define PLUGINCODEC_OPTION_CUSMFS			"Generic Parameter 4"
377 #define PLUGINCODEC_OPTION_STATICMBPS	    "Generic Parameter 7"
378 #define PLUGINCODEC_OPTION_MAXNALSIZE	    "Generic Parameter 9"
379 
380 #define H264_H323_RFC3984	OpalPluginCodec_Identifer_H264_Aligned   // Single NAL packetization H.241 Annex A
381 #define H264_ASPECT_43			2
382 #define H264_ASPECT_HD			13
383 
384 // NOTE: All these values are subject to change Values need to be confirmed!
385 #define H264_LEVEL1           15      // SQCIF  30 fps
386 #define H264_LEVEL1_MBPS      640
387 #define H264_LEVEL1_1         22      // QCIF 30 fps
388 #define H264_LEVEL1_1_MBPS    1920
389 #define H264_LEVEL1_2         29
390 #define H264_LEVEL1_2_MBPS    3840
391 #define H264_LEVEL1_3         36      //  CIF 30 fps
392 #define H264_LEVEL1_3_MBPS    3840
393 #define H264_LEVEL2_1         50
394 #define H264_LEVEL2_1_MBPS    5120    //
395 #define H264_LEVEL2_2         57
396 #define H264_LEVEL2_2_MBPS    5120
397 #define H264_LEVEL3           64      // 720p 30fps
398 #define H264_LEVEL3_MBPS      12000
399 #define H264_LEVEL3_1         71      // 720p 30fps
400 #define H264_LEVEL3_1_MBPS    14000
401 #define H264_LEVEL4           85      // 1080p 30fps
402 #define H264_LEVEL4_MBPS      20480
403 
404 
405 // H.264 QCIF
406 static const char     H264QCIF_Desc[]          = { "H.264-QCIF" };
407 static const char     H264QCIF_MediaFmt[]      = { "H.264-QCIF" };
408 static unsigned int   H264QCIF_FrameHeight     = QCIF_HEIGHT;
409 static unsigned int   H264QCIF_FrameWidth      = QCIF_WIDTH;
410 static unsigned int   H264QCIF_Profile         = H264_PROFILE_BASE;
411 static unsigned int   H264QCIF_Level           = H264_LEVEL1_1;
412 static unsigned int   H264QCIF_MaxBitRate      = H264_LEVEL1_1_MBPS*100;
413 static const char	  H264QCIF_TargetBitRate[]=  { "192000" };
414 static unsigned int   H264QCIF_VideoType       = PluginCodec_MediaTypeVideo;
415 static unsigned int   H264QCIF_Generic3        = 0;
416 static unsigned int   H264QCIF_Generic4        = 0;
417 static unsigned int   H264QCIF_Generic5        = 0;
418 static unsigned int   H264QCIF_Generic6        = 0;
419 static unsigned int   H264QCIF_Generic7        = 0;
420 static unsigned int   H264QCIF_Generic9        = 0;
421 static unsigned int   H264QCIF_Generic10       = 0; //H264_ASPECT_43;
422 static unsigned int   H264QCIF_Generic13       = 3000;
423 
424 
425 // H.264 CIF
426 static const char     H264CIF_Desc[]          = { "H.264-CIF" };
427 static const char     H264CIF_MediaFmt[]      = { "H.264-CIF" };
428 static unsigned int   H264CIF_FrameHeight     = CIF_HEIGHT;
429 static unsigned int   H264CIF_FrameWidth      = CIF_WIDTH;
430 static unsigned int   H264CIF_Profile         = H264_PROFILE_BASE;
431 static unsigned int   H264CIF_Level           = H264_LEVEL1_3;
432 static unsigned int   H264CIF_MaxBitRate      = H264_LEVEL1_3_MBPS*100;
433 static const char	  H264CIF_TargetBitRate[] =  { "384000" };
434 static unsigned int   H264CIF_VideoType       = PluginCodec_MediaTypeVideo;
435 static unsigned int   H264CIF_Generic3        = 0;
436 static unsigned int   H264CIF_Generic4        = 0;
437 static unsigned int   H264CIF_Generic5        = 0;
438 static unsigned int   H264CIF_Generic6        = 0;
439 static unsigned int   H264CIF_Generic7        = 0;
440 static unsigned int   H264CIF_Generic9        = 0;
441 static unsigned int   H264CIF_Generic10       = 0; //H264_ASPECT_43;
442 static unsigned int   H264CIF_Generic13       = 3000;
443 
444 
445 // H.264 VGA
446 static const char     H264VGA_Desc[]          = { "H.264-VGA" };
447 static const char     H264VGA_MediaFmt[]      = { "H.264-VGA" };
448 static unsigned int   H264VGA_FrameHeight     = VGA_HEIGHT;
449 static unsigned int   H264VGA_FrameWidth      = VGA_WIDTH;
450 static unsigned int   H264VGA_Profile         = H264_PROFILE_BASE;
451 static unsigned int   H264VGA_Level           = H264_LEVEL2_1;
452 static unsigned int   H264VGA_MaxBitRate      = H264_LEVEL2_1_MBPS*100;
453 static const char	  H264VGA_TargetBitRate[] =  { "512000" };
454 static unsigned int   H264VGA_VideoType       = PluginCodec_MediaTypeVideo;
455 static unsigned int   H264VGA_Generic3        = 72;
456 static unsigned int   H264VGA_Generic4        = 5;
457 static unsigned int   H264VGA_Generic5        = 0;
458 static unsigned int   H264VGA_Generic6        = 0;
459 static unsigned int   H264VGA_Generic7        = 0;
460 static unsigned int   H264VGA_Generic9        = 0;
461 static unsigned int   H264VGA_Generic10       = 0;
462 static unsigned int   H264VGA_Generic13       = 3000;
463 
464 
465 // H.264 CIF4   // compatible SIP profile
466 static const char     H264CIF4_Desc[]          = { "H.264-4CIF" };
467 static const char     H264CIF4_MediaFmt[]      = { "H.264-4CIF" };
468 static unsigned int   H264CIF4_FrameHeight     = CIF4_HEIGHT;
469 static unsigned int   H264CIF4_FrameWidth      = CIF4_WIDTH;
470 static unsigned int   H264CIF4_Profile         = H264_PROFILE_BASE; //+ H264_PROFILE_MAIN;
471 static unsigned int   H264CIF4_Level           = H264_LEVEL3;
472 static unsigned int   H264CIF4_MaxBitRate      = H264_LEVEL3_MBPS*100;
473 static const char	  H264CIF4_TargetBitRate[]=  { "10000000" };
474 static unsigned int   H264CIF4_VideoType       = PluginCodec_MediaTypeVideo; // | PluginCodec_MediaTypeExtVideo;
475 static unsigned int   H264CIF4_Generic3        = 0;
476 static unsigned int   H264CIF4_Generic4        = 0;
477 static unsigned int   H264CIF4_Generic5        = 0;
478 static unsigned int   H264CIF4_Generic6        = 0;
479 static unsigned int   H264CIF4_Generic7        = 0;
480 static unsigned int   H264CIF4_Generic9        = 0;
481 static unsigned int   H264CIF4_Generic10       = 0; //H264_ASPECT_43;
482 static unsigned int   H264CIF4_Generic13       = 3000;
483 
484 
485 // HD 720P
486 static const char     H264720P_Desc[]          = { "H.264-720" };
487 static const char     H264720P_MediaFmt[]      = { "H.264-720" };
488 static unsigned int   H264720P_FrameHeight     = P720_HEIGHT;
489 static unsigned int   H264720P_FrameWidth      = P720_WIDTH;
490 static unsigned int   H264720P_Profile         = H264_PROFILE_BASE;
491 static unsigned int   H264720P_Level           = H264_LEVEL3_1;
492 static unsigned int   H264720P_MaxBitRate      = H264_LEVEL4_MBPS*100; //H264_LEVEL3_1_MBPS*100;
493 static const char	  H264720P_TargetBitRate[] =  { "2048000" };
494 static unsigned int   H264720P_VideoType       = PluginCodec_MediaTypeVideo;
495 static unsigned int   H264720P_Generic3        = 231;
496 static unsigned int   H264720P_Generic4        = 15;
497 static unsigned int   H264720P_Generic5        = 0;
498 static unsigned int   H264720P_Generic6        = 0;
499 static unsigned int   H264720P_Generic7        = 0;
500 static unsigned int   H264720P_Generic9        = 0;
501 static unsigned int   H264720P_Generic10       = 0;    //H264_ASPECT_HD;
502 static unsigned int   H264720P_Generic13       = 3000;
503 
504 // HD H.239 1920 x 1152
505 static const char     H264H239_Desc[]           = { "H.264" };
506 static const char     H264H239_MediaFmt[]       = { "H.264" };
507 static unsigned int   H264H239_FrameHeight      = 1152;
508 static unsigned int   H264H239_FrameWidth       = 1920;
509 static unsigned int   H264H239_Profile          = H264_PROFILE_BASE;
510 static unsigned int   H264H239_Level            = H264_LEVEL4;
511 static unsigned int   H264H239_MaxBitRate       = 540000;
512 static const char     H264H239_TargetBitRate[]  = { "540000" };
513 static unsigned int   H264H239_VideoType        = PluginCodec_MediaTypeExtended | PluginCodec_MediaTypeH239;
514 static unsigned int   H264H239_Generic3         = 492;
515 static unsigned int   H264H239_Generic4         = 34;
516 static unsigned int   H264H239_Generic5         = 0;
517 static unsigned int   H264H239_Generic6         = 0;
518 static unsigned int   H264H239_Generic7         = 0;
519 static unsigned int   H264H239_Generic9         = 0;
520 static unsigned int   H264H239_Generic10        = 0; //H264_ASPECT_HD;
521 static unsigned int   H264H239_Generic13        = 3000;
522 
523 
524 static const char     H2641080P_Desc[]          = { "H.264-720" };
525 static const char     H2641080P_MediaFmt[]      = { "H.264-720" };
526 static unsigned int   H2641080P_FrameHeight     = P1080_HEIGHT;
527 static unsigned int   H2641080P_FrameWidth      = P1080_WIDTH;
528 static unsigned int   H2641080P_Profile         = H264_PROFILE_BASE; //H264_PROFILE_HIGH;
529 static unsigned int   H2641080P_Level           = H264_LEVEL2_2; //H264_LEVEL4;
530 static unsigned int   H2641080P_MaxBitRate      = H264_LEVEL4_MBPS*100;
531 static const char	  H2641080P_TargetBitRate[] =  { "2084000" };
532 static unsigned int   H2641080P_VideoType       = PluginCodec_MediaTypeVideo;
533 static unsigned int   H2641080P_Generic3        = 492;
534 static unsigned int   H2641080P_Generic4        = 32;
535 static unsigned int   H2641080P_Generic5        = 0;
536 static unsigned int   H2641080P_Generic6        = 0;
537 static unsigned int   H2641080P_Generic7        = 0;
538 static unsigned int   H2641080P_Generic9        = 0;
539 static unsigned int   H2641080P_Generic10       = 0; //H264_ASPECT_HD;
540 static unsigned int   H2641080P_Generic13       = 3000;
541 
542 
543 // MEGA MACRO to set options
544 #define DECLARE_GENERIC_OPTIONS(prefix) \
545 static struct PluginCodec_Option const prefix##_h323packetization = \
546  { PluginCodec_StringOption, PLUGINCODEC_MEDIA_PACKETIZATION, true, PluginCodec_EqualMerge, H264_H323_RFC3984 }; \
547 static struct PluginCodec_Option const prefix##_targetBitRate = \
548  { PluginCodec_IntegerOption, PLUGINCODEC_OPTION_TARGET_BIT_RATE,  true, PluginCodec_MinMerge, prefix##_TargetBitRate }; \
549 static struct PluginCodec_Option const * const prefix##_OptionTable[] = { \
550   &prefix##_h323packetization, \
551   &prefix##_targetBitRate, \
552   NULL \
553 }; \
554 static const struct PluginCodec_H323GenericParameterDefinition prefix##_h323params[] = \
555 { \
556 	{{1,0,0,0,0},3, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {prefix##_Generic3}}, \
557 	{{1,0,0,0,0},4, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {prefix##_Generic4}}, \
558 	{{1,0,0,0,0},5, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {prefix##_Generic5}}, \
559 	{{1,0,0,0,0},6, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {prefix##_Generic6}}, \
560 	{{1,0,0,0,0},7, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {prefix##_Generic7}}, \
561 	{{1,0,0,0,0},9, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_Unsigned32Min, {prefix##_Generic9}}, \
562 	{{1,0,0,0,0},10, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {prefix##_Generic10}}, \
563 	{{1,0,0,0,0},13, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {prefix##_Generic13}}, \
564 	{{1,0,0,0,0},41, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_BooleanArray,{prefix##_Profile}}, \
565 	{{1,0,0,0,0},42, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {prefix##_Level}}, \
566 }; \
567 static struct PluginCodec_H323GenericCodecData prefix##_h323GenericData[] = { \
568     { OpalPluginCodec_Identifer_H264_Generic, prefix##_MaxBitRate, 10, prefix##_h323params } \
569 }; \
570 
571 DECLARE_GENERIC_OPTIONS(H264QCIF)
572 DECLARE_GENERIC_OPTIONS(H264CIF)
573 DECLARE_GENERIC_OPTIONS(H264VGA)
574 DECLARE_GENERIC_OPTIONS(H264CIF4)
575 DECLARE_GENERIC_OPTIONS(H264720P)
576 DECLARE_GENERIC_OPTIONS(H264H239)
577 DECLARE_GENERIC_OPTIONS(H2641080P)
578 
579 #define DECLARE_H323PARAM(prefix) \
580 { \
581   /* encoder */ \
582   PLUGIN_CODEC_VERSION_OPTIONS,	      /* codec API version */ \
583   &licenseInfo,                       /* license information */ \
584   prefix##_VideoType |                /* video type */ \
585   PluginCodec_RTPTypeShared |         /* specified RTP type */ \
586   PluginCodec_RTPTypeDynamic,         /* specified RTP type */ \
587   prefix##_Desc,                      /* text decription */ \
588   YUV420PDesc,                        /* source format */ \
589   prefix##_MediaFmt,                  /* destination format */ \
590   prefix##_OptionTable,			      /* user data */ \
591   H264_CLOCKRATE,                     /* samples per second */ \
592   prefix##_MaxBitRate,				  /* raw bits per second */ \
593   20000,                              /* nanoseconds per frame */ \
594   {{ prefix##_FrameWidth,             /* samples per frame */ \
595   prefix##_FrameHeight,			      /* bytes per frame */ \
596   10,                                 /* recommended number of frames per packet */ \
597   60, }},                             /* maximum number of frames per packet  */ \
598   0,                                  /* IANA RTP payload code */ \
599   sdpH264,                            /* RTP payload name */ \
600   create_encoder,                     /* create codec function */ \
601   destroy_encoder,                    /* destroy codec */ \
602   codec_encoder,                      /* encode/decode */ \
603   EncoderControls,                    /* codec controls */ \
604   PluginCodec_H323Codec_generic,      /* h323CapabilityType */ \
605   (struct PluginCodec_H323GenericCodecData *)&prefix##_h323GenericData /* h323CapabilityData */ \
606 }, \
607 {  \
608   /* decoder */ \
609   PLUGIN_CODEC_VERSION_OPTIONS,	      /* codec API version */ \
610   &licenseInfo,                       /* license information */ \
611   prefix##_VideoType |                /* video codec */ \
612   PluginCodec_RTPTypeShared |         /* specified RTP type */ \
613   PluginCodec_RTPTypeDynamic,         /* specified RTP type */ \
614   prefix##_Desc,                      /* text decription */ \
615   prefix##_MediaFmt,                  /* source format */ \
616   YUV420PDesc,                        /* destination format */ \
617   prefix##_OptionTable,			      /* user data */ \
618   H264_CLOCKRATE,                     /* samples per second */ \
619   prefix##_MaxBitRate,				  /* raw bits per second */ \
620   20000,                              /* nanoseconds per frame */ \
621   {{ prefix##_FrameWidth,             /* samples per frame */ \
622   prefix##_FrameHeight,			      /* bytes per frame */ \
623   10,                                 /* recommended number of frames per packet */ \
624   60, }},                             /* maximum number of frames per packet  */ \
625   0,                                  /* IANA RTP payload code */ \
626   sdpH264,                            /* RTP payload name */ \
627   create_decoder,                     /* create codec function */ \
628   destroy_decoder,                    /* destroy codec */ \
629   codec_decoder,                      /* encode/decode */ \
630   DecoderControls,                    /* codec controls */ \
631   PluginCodec_H323Codec_generic,      /* h323CapabilityType */ \
632   (struct PluginCodec_H323GenericCodecData *)&prefix##_h323GenericData /* h323CapabilityData */ \
633 }
634 
635 /////////////////////////////////////////////////////////////////////////////
636 
637 static struct PluginCodec_Definition h264CodecDefn[] = {
638  // DECLARE_H323PARAM(H264QCIF),
639    DECLARE_H323PARAM(H264CIF),
640  // DECLARE_H323PARAM(H264VGA),
641  // DECLARE_H323PARAM(H264CIF4)
642  // DECLARE_H323PARAM(H264720P),
643    DECLARE_H323PARAM(H264H239)
644   ,DECLARE_H323PARAM(H2641080P)
645 };
646 
647 #endif /* __H264-X264_H__ */
648