Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 11

ಲೇಖನದ ವಸ್ತುವನ್ನು ನನ್ನಿಂದ ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ ಝೆನ್ ಚಾನೆಲ್.

Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 11

ಡೇಟಾ ಚಲನೆಯ ಕಾರ್ಯವಿಧಾನ

  • ಡೇಟಾ ಬ್ಲಾಕ್ dblk_t
  • ಸಂದೇಶ mblk_t
  • ಸಂದೇಶಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವ ಕಾರ್ಯಗಳು mblk_t
  • ಸರತಿ ಸಾಲು_t
  • ಕ್ಯೂಗಳು ಕ್ಯೂ_ಟಿಯೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವ ಕಾರ್ಯಗಳು
  • ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ
  • ಡೇಟಾ ಸಂಸ್ಕರಣಾ ಗ್ರಾಫ್ನ ಸಿಗ್ನಲ್ ಪಾಯಿಂಟ್
  • ಟಿಕ್ಕರ್‌ನ ತೆರೆಮರೆಯ ಚಟುವಟಿಕೆಗಳು
  • ಬಫರೈಸರ್ (MSBufferizer)
  • MSBufferizer ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವ ಕಾರ್ಯಗಳು

ಕೊನೆಯಲ್ಲಿ ಲೇಖನ ನಾವು ನಮ್ಮದೇ ಆದ ಫಿಲ್ಟರ್ ಅನ್ನು ಅಭಿವೃದ್ಧಿಪಡಿಸಿದ್ದೇವೆ. ಈ ಲೇಖನವು ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್ ಫಿಲ್ಟರ್‌ಗಳ ನಡುವೆ ಡೇಟಾವನ್ನು ಚಲಿಸುವ ಆಂತರಿಕ ಕಾರ್ಯವಿಧಾನದ ಮೇಲೆ ಕೇಂದ್ರೀಕರಿಸುತ್ತದೆ. ಭವಿಷ್ಯದಲ್ಲಿ ಕಡಿಮೆ ಪ್ರಯತ್ನದಲ್ಲಿ ಅತ್ಯಾಧುನಿಕ ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಬರೆಯಲು ಇದು ನಿಮ್ಮನ್ನು ಅನುಮತಿಸುತ್ತದೆ.

ಡೇಟಾ ಚಲನೆಯ ಕಾರ್ಯವಿಧಾನ

ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್‌ನಲ್ಲಿನ ಡೇಟಾ ಚಲನೆಯನ್ನು ರಚನೆಯಿಂದ ವಿವರಿಸಿದ ಸರತಿ ಸಾಲುಗಳನ್ನು ಬಳಸಿ ನಿರ್ವಹಿಸಲಾಗುತ್ತದೆ ಕ್ಯೂ_ಟಿ. ಮುಂತಾದ ಸಂದೇಶಗಳ ಸರಮಾಲೆಗಳು mblk_t, ಇದು ಸ್ವತಃ ಸಿಗ್ನಲ್ ಡೇಟಾವನ್ನು ಹೊಂದಿರುವುದಿಲ್ಲ, ಆದರೆ ಹಿಂದಿನ, ಮುಂದಿನ ಸಂದೇಶಕ್ಕೆ ಮತ್ತು ಡೇಟಾ ಬ್ಲಾಕ್‌ಗೆ ಮಾತ್ರ ಲಿಂಕ್ ಮಾಡುತ್ತದೆ. ಹೆಚ್ಚುವರಿಯಾಗಿ, ಒಂದೇ ರೀತಿಯ ಸಂದೇಶಕ್ಕೆ ಲಿಂಕ್‌ಗಾಗಿ ಕ್ಷೇತ್ರವೂ ಇದೆ ಎಂದು ನಾನು ವಿಶೇಷವಾಗಿ ಒತ್ತಿಹೇಳಲು ಬಯಸುತ್ತೇನೆ, ಇದು ಸಂದೇಶಗಳ ಏಕ-ಸಂಯೋಜಿತ ಪಟ್ಟಿಯನ್ನು ಸಂಘಟಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಅಂತಹ ಪಟ್ಟಿಯಿಂದ ಒಂದುಗೂಡಿದ ಸಂದೇಶಗಳ ಗುಂಪನ್ನು ನಾವು ಟುಪಲ್ ಎಂದು ಕರೆಯುತ್ತೇವೆ. ಹೀಗಾಗಿ, ಸರದಿಯ ಯಾವುದೇ ಅಂಶವು ಒಂದೇ ಸಂದೇಶವಾಗಿರಬಹುದು mblk_t, ಮತ್ತು ಬಹುಶಃ ಸಂದೇಶ ಟುಪಲ್‌ನ ಮುಖ್ಯಸ್ಥ mblk_t. ಪ್ರತಿಯೊಂದು ಟುಪಲ್ ಸಂದೇಶವು ತನ್ನದೇ ಆದ ವಾರ್ಡ್ ಡೇಟಾ ಬ್ಲಾಕ್ ಅನ್ನು ಹೊಂದಬಹುದು. ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ ಟುಪಲ್ಸ್ ಏಕೆ ಬೇಕು ಎಂದು ನಾವು ಚರ್ಚಿಸುತ್ತೇವೆ.

ಮೇಲೆ ಹೇಳಿದಂತೆ, ಸಂದೇಶವು ಡೇಟಾದ ಬ್ಲಾಕ್ ಅನ್ನು ಹೊಂದಿರುವುದಿಲ್ಲ; ಬದಲಿಗೆ, ಇದು ಬ್ಲಾಕ್ ಅನ್ನು ಸಂಗ್ರಹಿಸಿರುವ ಮೆಮೊರಿ ಪ್ರದೇಶಕ್ಕೆ ಪಾಯಿಂಟರ್ ಅನ್ನು ಮಾತ್ರ ಒಳಗೊಂಡಿದೆ. ಈ ಭಾಗದಲ್ಲಿ, ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮರ್‌ನ ಕೆಲಸದ ಒಟ್ಟಾರೆ ಚಿತ್ರವು "ಮಾನ್ಸ್ಟರ್ಸ್, ಇಂಕ್" ಎಂಬ ಕಾರ್ಟೂನ್‌ನಲ್ಲಿನ ಬಾಗಿಲಿನ ಗೋದಾಮಿನ ನೆನಪಿಸುತ್ತದೆ, ಅಲ್ಲಿ ಬಾಗಿಲುಗಳು (ಡೇಟಾ - ಕೊಠಡಿಗಳಿಗೆ ಲಿಂಕ್‌ಗಳು) ಓವರ್‌ಹೆಡ್ ಕನ್ವೇಯರ್‌ಗಳ ಉದ್ದಕ್ಕೂ ಹುಚ್ಚು ವೇಗದಲ್ಲಿ ಚಲಿಸುತ್ತವೆ, ಆದರೆ ಕೊಠಡಿಗಳು ಸ್ವತಃ. ಚಲನರಹಿತವಾಗಿ ಉಳಿಯುತ್ತವೆ.

ಈಗ, ಕ್ರಮಾನುಗತದಲ್ಲಿ ಕೆಳಗಿನಿಂದ ಮೇಲಕ್ಕೆ ಚಲಿಸುವಾಗ, ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮರ್‌ನಲ್ಲಿ ಡೇಟಾ ಟ್ರಾನ್ಸ್‌ಮಿಷನ್ ಯಾಂತ್ರಿಕತೆಯ ಪಟ್ಟಿ ಮಾಡಲಾದ ಘಟಕಗಳನ್ನು ವಿವರವಾಗಿ ಪರಿಗಣಿಸೋಣ.

ಡೇಟಾ ಬ್ಲಾಕ್ dblk_t

ಡೇಟಾ ಬ್ಲಾಕ್ ಹೆಡರ್ ಮತ್ತು ಡೇಟಾ ಬಫರ್ ಅನ್ನು ಒಳಗೊಂಡಿದೆ. ಶಿರೋಲೇಖವನ್ನು ಈ ಕೆಳಗಿನ ರಚನೆಯಿಂದ ವಿವರಿಸಲಾಗಿದೆ,

typedef struct datab
{
unsigned char *db_base; // Указатель на начало буфер данных.
unsigned char *db_lim;  // Указатель на конец буфер данных.
void (*db_freefn)(void*); // Функция освобождения памяти при удалении блока.
int db_ref; // Счетчик ссылок.
} dblk_t;

ರಚನೆಯ ಕ್ಷೇತ್ರಗಳು ಬಫರ್‌ನ ಪ್ರಾರಂಭ, ಬಫರ್‌ನ ಅಂತ್ಯ ಮತ್ತು ಡೇಟಾ ಬಫರ್ ಅನ್ನು ಅಳಿಸುವ ಕಾರ್ಯಕ್ಕೆ ಪಾಯಿಂಟರ್‌ಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತವೆ. ಹೆಡರ್‌ನಲ್ಲಿ ಕೊನೆಯ ಅಂಶ db_ref - ಉಲ್ಲೇಖ ಕೌಂಟರ್, ಅದು ಶೂನ್ಯವನ್ನು ತಲುಪಿದರೆ, ಮೆಮೊರಿಯಿಂದ ಈ ಬ್ಲಾಕ್ ಅನ್ನು ಅಳಿಸಲು ಇದು ಸಂಕೇತವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ಕಾರ್ಯದಿಂದ ಡೇಟಾ ಬ್ಲಾಕ್ ಅನ್ನು ರಚಿಸಿದ್ದರೆ datab_alloc() , ನಂತರ ಡೇಟಾ ಬಫರ್ ಅನ್ನು ಹೆಡರ್ ನಂತರ ತಕ್ಷಣವೇ ಮೆಮೊರಿಯಲ್ಲಿ ಇರಿಸಲಾಗುತ್ತದೆ. ಎಲ್ಲಾ ಇತರ ಸಂದರ್ಭಗಳಲ್ಲಿ, ಬಫರ್ ಎಲ್ಲೋ ಪ್ರತ್ಯೇಕವಾಗಿ ನೆಲೆಗೊಳ್ಳಬಹುದು. ಡೇಟಾ ಬಫರ್ ನಾವು ಫಿಲ್ಟರ್‌ಗಳೊಂದಿಗೆ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಬಯಸುವ ಸಿಗ್ನಲ್ ಮಾದರಿಗಳು ಅಥವಾ ಇತರ ಡೇಟಾವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ.

ಕಾರ್ಯವನ್ನು ಬಳಸಿಕೊಂಡು ಡೇಟಾ ಬ್ಲಾಕ್‌ನ ಹೊಸ ನಿದರ್ಶನವನ್ನು ರಚಿಸಲಾಗಿದೆ:

dblk_t *datab_alloc(int size);

ಇನ್‌ಪುಟ್ ಪ್ಯಾರಾಮೀಟರ್ ಆಗಿ, ಬ್ಲಾಕ್ ಸಂಗ್ರಹಿಸುವ ಡೇಟಾದ ಗಾತ್ರವನ್ನು ನೀಡಲಾಗುತ್ತದೆ. ಹಂಚಿಕೆ ಮಾಡಲಾದ ಮೆಮೊರಿಯ ಪ್ರಾರಂಭದಲ್ಲಿ ಹೆಡರ್ - ರಚನೆಯನ್ನು ಇರಿಸಲು ಹೆಚ್ಚಿನ ಮೆಮೊರಿಯನ್ನು ಹಂಚಲಾಗುತ್ತದೆ ಡೇಟಾಬ್. ಆದರೆ ಇತರ ಕಾರ್ಯಗಳನ್ನು ಬಳಸುವಾಗ, ಇದು ಯಾವಾಗಲೂ ಸಂಭವಿಸುವುದಿಲ್ಲ; ಕೆಲವು ಸಂದರ್ಭಗಳಲ್ಲಿ, ಡೇಟಾ ಬಫರ್ ಡೇಟಾ ಬ್ಲಾಕ್ ಹೆಡರ್‌ನಿಂದ ಪ್ರತ್ಯೇಕವಾಗಿ ನೆಲೆಗೊಂಡಿರಬಹುದು. ರಚನೆಯನ್ನು ರಚಿಸುವಾಗ, ಕ್ಷೇತ್ರಗಳನ್ನು ಅದರ ಕ್ಷೇತ್ರವನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗುತ್ತದೆ db_base ಡೇಟಾ ಪ್ರದೇಶದ ಆರಂಭವನ್ನು ಸೂಚಿಸಿದರು, ಮತ್ತು db_lim ಅದರ ಕೊನೆಯವರೆಗೆ. ಲಿಂಕ್ ಎಣಿಕೆ db_ref ಒಂದಕ್ಕೆ ಹೊಂದಿಸಲಾಗಿದೆ. ಡೇಟಾ ಕ್ಲಿಯರ್ ಫಂಕ್ಷನ್ ಪಾಯಿಂಟರ್ ಅನ್ನು ಶೂನ್ಯಕ್ಕೆ ಹೊಂದಿಸಲಾಗಿದೆ.

ಸಂದೇಶ mblk_t

ಹೇಳಿದಂತೆ, ಸರದಿ ಅಂಶಗಳು ಪ್ರಕಾರವಾಗಿದೆ mblk_t, ಇದನ್ನು ಈ ಕೆಳಗಿನಂತೆ ವ್ಯಾಖ್ಯಾನಿಸಲಾಗಿದೆ:

typedef struct msgb
{
  struct msgb *b_prev;   // Указатель на предыдущий элемент списка.
  struct msgb *b_next;   // Указатель на следующий элемент списка.
  struct msgb *b_cont;   // Указатель для подклейки к сообщению других сообщений, для создания кортежа сообщений.
  struct datab *b_datap; // Указатель на структуру блока данных.
  unsigned char *b_rptr; // Указатель на начало области данных для чтения данных буфера b_datap.
  unsigned char *b_wptr; // Указатель на начало области данных для записи данных буфера b_datap.
  uint32_t reserved1;    // Зарезервированное поле1, медиастример помещает туда служебную информацию. 
  uint32_t reserved2;    // Зарезервированное поле2, медиастример помещает туда служебную информацию.
  #if defined(ORTP_TIMESTAMP)
  struct timeval timestamp;
  #endif
  ortp_recv_addr_t recv_addr;
} mblk_t;

ರಚನೆ mblk_t ಆರಂಭದಲ್ಲಿ ಪಾಯಿಂಟರ್‌ಗಳನ್ನು ಒಳಗೊಂಡಿದೆ b_prev, b_ಮುಂದೆ, ದ್ವಿಗುಣವಾಗಿ ಲಿಂಕ್ ಮಾಡಲಾದ ಪಟ್ಟಿಯನ್ನು ಸಂಘಟಿಸಲು ಇದು ಅವಶ್ಯಕವಾಗಿದೆ (ಇದು ಸರದಿ ಕ್ಯೂ_ಟಿ).

ನಂತರ ಪಾಯಿಂಟರ್ ಬರುತ್ತದೆ b_cont, ಸಂದೇಶವು ಟುಪಲ್‌ನ ಭಾಗವಾಗಿದ್ದಾಗ ಮಾತ್ರ ಬಳಸಲ್ಪಡುತ್ತದೆ. ಟುಪಲ್‌ನಲ್ಲಿನ ಕೊನೆಯ ಸಂದೇಶಕ್ಕಾಗಿ, ಈ ಪಾಯಿಂಟರ್ ಶೂನ್ಯವಾಗಿರುತ್ತದೆ.

ಮುಂದೆ ನಾವು ಡೇಟಾ ಬ್ಲಾಕ್ಗೆ ಪಾಯಿಂಟರ್ ಅನ್ನು ನೋಡುತ್ತೇವೆ b_datap, ಇದಕ್ಕಾಗಿ ಸಂದೇಶವು ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ. ಬ್ಲಾಕ್ ಡೇಟಾ ಬಫರ್ ಒಳಗಿನ ಪ್ರದೇಶಕ್ಕೆ ಪಾಯಿಂಟರ್‌ಗಳು ಇದನ್ನು ಅನುಸರಿಸುತ್ತವೆ. ಕ್ಷೇತ್ರ b_rptr ಬಫರ್‌ನಿಂದ ಡೇಟಾವನ್ನು ಓದುವ ಸ್ಥಳವನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸುತ್ತದೆ. ಕ್ಷೇತ್ರ b_wptr ಬಫರ್‌ಗೆ ಬರೆಯುವ ಸ್ಥಳವನ್ನು ಸೂಚಿಸುತ್ತದೆ.

ಉಳಿದ ಕ್ಷೇತ್ರಗಳು ಸೇವಾ ಸ್ವರೂಪವನ್ನು ಹೊಂದಿವೆ ಮತ್ತು ಡೇಟಾ ವರ್ಗಾವಣೆ ಕಾರ್ಯವಿಧಾನದ ಕಾರ್ಯಾಚರಣೆಗೆ ಸಂಬಂಧಿಸಿಲ್ಲ.

ಹೆಸರಿನೊಂದಿಗೆ ಒಂದೇ ಸಂದೇಶವನ್ನು ಕೆಳಗೆ ನೀಡಲಾಗಿದೆ m1 ಮತ್ತು ಡೇಟಾ ಬ್ಲಾಕ್ d1.
Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 11
ಕೆಳಗಿನ ಚಿತ್ರವು ಮೂರು ಸಂದೇಶಗಳ ಟ್ಯೂಪಲ್ ಅನ್ನು ತೋರಿಸುತ್ತದೆ m1, ಮೀ1_1, ಮೀ1_2.
Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 11

ಸಂದೇಶ ಕಾರ್ಯಗಳು mblk_t

ಹೊಸ ಸಂದೇಶ mblk_t ಕಾರ್ಯದಿಂದ ರಚಿಸಲಾಗಿದೆ:

mblk_t *allocb(int size, int pri); 

ಅವಳು ನೆನಪಿಗಾಗಿ ಹೊಸ ಸಂದೇಶವನ್ನು ಇಡುತ್ತಾಳೆ mblk_t ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ ಗಾತ್ರದ ಡೇಟಾ ಬ್ಲಾಕ್ನೊಂದಿಗೆ ಗಾತ್ರ, ಎರಡನೇ ವಾದ - ಬೆಲೆ ಗ್ರಂಥಾಲಯದ ಈ ಆವೃತ್ತಿಯಲ್ಲಿ ಬಳಸಲಾಗಿಲ್ಲ. ಅದು ಶೂನ್ಯವಾಗಿ ಉಳಿಯಬೇಕು. ಕಾರ್ಯದ ಕಾರ್ಯಾಚರಣೆಯ ಸಮಯದಲ್ಲಿ, ಹೊಸ ಸಂದೇಶದ ರಚನೆಗಾಗಿ ಮೆಮೊರಿಯನ್ನು ಹಂಚಲಾಗುತ್ತದೆ ಮತ್ತು ಕಾರ್ಯವನ್ನು ಕರೆಯಲಾಗುತ್ತದೆ mblk_init(), ಇದು ರಚನೆಯ ರಚಿಸಿದ ನಿದರ್ಶನದ ಎಲ್ಲಾ ಕ್ಷೇತ್ರಗಳನ್ನು ಮರುಹೊಂದಿಸುತ್ತದೆ ಮತ್ತು ನಂತರ, ಮೇಲೆ ತಿಳಿಸಿದ ಬಳಸಿ datab_alloc(), ಡೇಟಾ ಬಫರ್ ಅನ್ನು ರಚಿಸುತ್ತದೆ. ಅದರ ನಂತರ ರಚನೆಯಲ್ಲಿನ ಕ್ಷೇತ್ರಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗುತ್ತದೆ:

mp->b_datap=datab;
mp->b_rptr=mp->b_wptr=datab->db_base;
mp->b_next=mp->b_prev=mp->b_cont=NULL;

ಔಟ್‌ಪುಟ್‌ನಲ್ಲಿ ನಾವು ಪ್ರಾರಂಭಿಕ ಕ್ಷೇತ್ರಗಳು ಮತ್ತು ಖಾಲಿ ಡೇಟಾ ಬಫರ್‌ನೊಂದಿಗೆ ಹೊಸ ಸಂದೇಶವನ್ನು ಸ್ವೀಕರಿಸುತ್ತೇವೆ. ಸಂದೇಶಕ್ಕೆ ಡೇಟಾವನ್ನು ಸೇರಿಸಲು, ನೀವು ಅದನ್ನು ಡೇಟಾ ಬ್ಲಾಕ್ ಬಫರ್‌ಗೆ ನಕಲಿಸಬೇಕಾಗುತ್ತದೆ:

memcpy(msg->b_rptr, data, size);

ಅಲ್ಲಿ ಡೇಟಾ ಡೇಟಾ ಮೂಲಕ್ಕೆ ಪಾಯಿಂಟರ್ ಆಗಿದೆ, ಮತ್ತು ಗಾತ್ರ - ಅವುಗಳ ಗಾತ್ರ.
ನಂತರ ನೀವು ಪಾಯಿಂಟರ್ ಅನ್ನು ಬರೆಯುವ ಬಿಂದುವಿಗೆ ನವೀಕರಿಸಬೇಕು ಇದರಿಂದ ಅದು ಬಫರ್‌ನಲ್ಲಿನ ಮುಕ್ತ ಪ್ರದೇಶದ ಪ್ರಾರಂಭಕ್ಕೆ ಮತ್ತೆ ಸೂಚಿಸುತ್ತದೆ:

msg->b_wptr = msg->b_wptr + size

ನೀವು ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಬಫರ್‌ನಿಂದ ಸಂದೇಶವನ್ನು ರಚಿಸಬೇಕಾದರೆ, ನಕಲಿಸದೆ, ನಂತರ ಕಾರ್ಯವನ್ನು ಬಳಸಿ:

mblk_t *esballoc(uint8_t *buf, int size, int pri, void (*freefn)(void*)); 

ಕಾರ್ಯವು ಸಂದೇಶವನ್ನು ರಚಿಸಿದ ನಂತರ ಮತ್ತು ಡೇಟಾ ಬ್ಲಾಕ್ನ ರಚನೆಯನ್ನು ವಿಳಾಸದಲ್ಲಿ ಡೇಟಾಗೆ ಅದರ ಪಾಯಿಂಟರ್ಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡುತ್ತದೆ ಬಫ್. ಆ. ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಡೇಟಾ ಬ್ಲಾಕ್‌ನ ಹೆಡರ್ ಕ್ಷೇತ್ರಗಳ ನಂತರ ಡೇಟಾ ಬಫರ್ ನೆಲೆಗೊಂಡಿಲ್ಲ, ಕಾರ್ಯದೊಂದಿಗೆ ಡೇಟಾ ಬ್ಲಾಕ್ ಅನ್ನು ರಚಿಸುವಾಗ ಇದ್ದಂತೆ datab_alloc(). ಕಾರ್ಯಕ್ಕೆ ರವಾನಿಸಲಾದ ಡೇಟಾದೊಂದಿಗೆ ಬಫರ್ ಅದು ಇದ್ದ ಸ್ಥಳದಲ್ಲಿಯೇ ಉಳಿಯುತ್ತದೆ, ಆದರೆ ಪಾಯಿಂಟರ್‌ಗಳ ಸಹಾಯದಿಂದ ಅದನ್ನು ಡೇಟಾ ಬ್ಲಾಕ್‌ನ ಹೊಸದಾಗಿ ರಚಿಸಲಾದ ಹೆಡರ್‌ಗೆ ಲಗತ್ತಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಅದರ ಪ್ರಕಾರ ಸಂದೇಶಕ್ಕೆ.

ಒಂದು ಸಂದೇಶಕ್ಕೆ mblk_t ಹಲವಾರು ಡೇಟಾ ಬ್ಲಾಕ್‌ಗಳನ್ನು ಅನುಕ್ರಮವಾಗಿ ಜೋಡಿಸಬಹುದು. ಇದನ್ನು ಕಾರ್ಯದಿಂದ ಮಾಡಲಾಗುತ್ತದೆ:

mblk_t * appendb(mblk_t *mp, const char *data, int size, bool_t pad); 

mp - ಮತ್ತೊಂದು ಡೇಟಾ ಬ್ಲಾಕ್ ಅನ್ನು ಸೇರಿಸುವ ಸಂದೇಶ;
ಡೇಟಾ - ಬ್ಲಾಕ್‌ಗೆ ಪಾಯಿಂಟರ್, ಅದರ ನಕಲನ್ನು ಸಂದೇಶಕ್ಕೆ ಸೇರಿಸಲಾಗುತ್ತದೆ;
ಗಾತ್ರ - ಡೇಟಾ ಗಾತ್ರ;
ಪ್ಯಾಡ್ - ನಿಯೋಜಿಸಲಾದ ಮೆಮೊರಿಯ ಗಾತ್ರವನ್ನು 4-ಬೈಟ್ ಗಡಿಯ ಉದ್ದಕ್ಕೂ ಜೋಡಿಸಬೇಕಾದ ಫ್ಲ್ಯಾಗ್ (ಪ್ಯಾಡಿಂಗ್ ಅನ್ನು ಸೊನ್ನೆಗಳೊಂದಿಗೆ ಮಾಡಲಾಗುತ್ತದೆ).

ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಸಂದೇಶ ಡೇಟಾ ಬಫರ್‌ನಲ್ಲಿ ಸಾಕಷ್ಟು ಸ್ಥಳಾವಕಾಶವಿದ್ದರೆ, ಹೊಸ ಡೇಟಾವನ್ನು ಈಗಾಗಲೇ ಇರುವ ಡೇಟಾದ ಹಿಂದೆ ಅಂಟಿಸಲಾಗುತ್ತದೆ. ಸಂದೇಶ ಡೇಟಾ ಬಫರ್‌ನಲ್ಲಿ ಕಡಿಮೆ ಸ್ಥಳಾವಕಾಶವಿದ್ದರೆ ಗಾತ್ರ, ನಂತರ ಸಾಕಷ್ಟು ಬಫರ್ ಗಾತ್ರದೊಂದಿಗೆ ಹೊಸ ಸಂದೇಶವನ್ನು ರಚಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಡೇಟಾವನ್ನು ಅದರ ಬಫರ್‌ಗೆ ನಕಲಿಸಲಾಗುತ್ತದೆ. ಇದು ಹೊಸ ಸಂದೇಶವಾಗಿದ್ದು, ಪಾಯಿಂಟರ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಮೂಲಕ್ಕೆ ಲಿಂಕ್ ಮಾಡಲಾಗಿದೆ b_cont. ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಸಂದೇಶವು ಟುಪಲ್ ಆಗಿ ಬದಲಾಗುತ್ತದೆ.

ನೀವು ಟುಪಲ್‌ಗೆ ಮತ್ತೊಂದು ಬ್ಲಾಕ್ ಡೇಟಾವನ್ನು ಸೇರಿಸಬೇಕಾದರೆ, ನೀವು ಕಾರ್ಯವನ್ನು ಬಳಸಬೇಕಾಗುತ್ತದೆ:

void msgappend(mblk_t *mp, const char *data, int size, bool_t pad);

ಅವಳು ಟುಪಲ್‌ನಲ್ಲಿ ಕೊನೆಯ ಸಂದೇಶವನ್ನು ಕಂಡುಕೊಳ್ಳುತ್ತಾಳೆ (ಅವನು ಹೊಂದಿದ್ದಾನೆ b_cont ಶೂನ್ಯವಾಗಿರುತ್ತದೆ) ಮತ್ತು ಈ ಸಂದೇಶಕ್ಕಾಗಿ ಕಾರ್ಯವನ್ನು ಕರೆಯುತ್ತದೆ appendb().

ಕಾರ್ಯವನ್ನು ಬಳಸಿಕೊಂಡು ಸಂದೇಶ ಅಥವಾ ಟುಪಲ್‌ನಲ್ಲಿನ ಡೇಟಾದ ಗಾತ್ರವನ್ನು ನೀವು ಕಂಡುಹಿಡಿಯಬಹುದು:

int msgdsize(const mblk_t *mp);

ಇದು ಟುಪಲ್‌ನಲ್ಲಿರುವ ಎಲ್ಲಾ ಸಂದೇಶಗಳ ಮೂಲಕ ಲೂಪ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಆ ಸಂದೇಶಗಳ ಡೇಟಾ ಬಫರ್‌ಗಳಲ್ಲಿನ ಒಟ್ಟು ಡೇಟಾವನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ. ಪ್ರತಿ ಸಂದೇಶಕ್ಕೆ, ಡೇಟಾದ ಮೊತ್ತವನ್ನು ಈ ಕೆಳಗಿನಂತೆ ಲೆಕ್ಕಹಾಕಲಾಗುತ್ತದೆ:

 mp->b_wptr - mp->b_rptr

ಎರಡು ಟುಪಲ್‌ಗಳನ್ನು ಸಂಯೋಜಿಸಲು, ಕಾರ್ಯವನ್ನು ಬಳಸಿ:

mblk_t *concatb(mblk_t *mp, mblk_t *newm);

ಅವಳು ತುಪ್ಪಳವನ್ನು ಸೇರಿಸುತ್ತಾಳೆ ಹೊಸ ಟುಪಲ್ನ ಬಾಲಕ್ಕೆ mp ಮತ್ತು ಫಲಿತಾಂಶದ ಟುಪಲ್‌ನ ಕೊನೆಯ ಸಂದೇಶಕ್ಕೆ ಪಾಯಿಂಟರ್ ಅನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ.

ಅಗತ್ಯವಿದ್ದರೆ, ಒಂದೇ ಬ್ಲಾಕ್ ಡೇಟಾದೊಂದಿಗೆ ಟ್ಯೂಪಲ್ ಅನ್ನು ಒಂದು ಸಂದೇಶವಾಗಿ ಪರಿವರ್ತಿಸಬಹುದು; ಇದನ್ನು ಕಾರ್ಯದಿಂದ ಮಾಡಲಾಗುತ್ತದೆ:

void msgpullup(mblk_t *mp,int len);

ವಾದ ವೇಳೆ ಲೆನ್ -1 ಆಗಿದೆ, ನಂತರ ಹಂಚಲಾದ ಬಫರ್‌ನ ಗಾತ್ರವನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿರ್ಧರಿಸಲಾಗುತ್ತದೆ. ಒಂದು ವೇಳೆ ಲೆನ್ ಧನಾತ್ಮಕ ಸಂಖ್ಯೆಯಾಗಿದೆ, ಈ ಗಾತ್ರದ ಬಫರ್ ಅನ್ನು ರಚಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಟುಪಲ್ ಸಂದೇಶ ಡೇಟಾವನ್ನು ಅದರೊಳಗೆ ನಕಲಿಸಲಾಗುತ್ತದೆ. ಬಫರ್ ಖಾಲಿಯಾದರೆ, ನಕಲು ಮಾಡುವುದು ಅಲ್ಲಿಗೆ ನಿಲ್ಲುತ್ತದೆ. ಟುಪಲ್‌ನ ಮೊದಲ ಸಂದೇಶವು ನಕಲಿಸಿದ ಡೇಟಾದೊಂದಿಗೆ ಹೊಸ ಗಾತ್ರದ ಬಫರ್ ಅನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ. ಉಳಿದ ಸಂದೇಶಗಳನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಮೆಮೊರಿಯು ರಾಶಿಗೆ ಮರಳುತ್ತದೆ.

ರಚನೆಯನ್ನು ಅಳಿಸುವಾಗ mblk_t ಕರೆ ಮಾಡುವಾಗ ಡೇಟಾ ಬ್ಲಾಕ್‌ನ ಉಲ್ಲೇಖದ ಸಂಖ್ಯೆಯನ್ನು ಗಣನೆಗೆ ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತದೆ freeb() ಅದು ಶೂನ್ಯವಾಗಿರುತ್ತದೆ, ನಂತರ ಡೇಟಾ ಬಫರ್ ಅನ್ನು ನಿದರ್ಶನದೊಂದಿಗೆ ಅಳಿಸಲಾಗುತ್ತದೆ mblk_t, ಇದು ಸೂಚಿಸುತ್ತದೆ.

ಹೊಸ ಸಂದೇಶದ ಕ್ಷೇತ್ರಗಳನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ:

void mblk_init(mblk_t *mp);

ಸಂದೇಶಕ್ಕೆ ಮತ್ತೊಂದು ಡೇಟಾವನ್ನು ಸೇರಿಸಲಾಗುತ್ತಿದೆ:

mblk_t * appendb(mblk_t *mp, const char *data, size_t size, bool_t pad);

ಹೊಸ ಡೇಟಾವು ಸಂದೇಶ ಡೇಟಾ ಬಫರ್‌ನ ಮುಕ್ತ ಜಾಗಕ್ಕೆ ಹೊಂದಿಕೆಯಾಗದಿದ್ದರೆ, ಅಗತ್ಯವಿರುವ ಗಾತ್ರದ ಬಫರ್‌ನೊಂದಿಗೆ ಪ್ರತ್ಯೇಕವಾಗಿ ರಚಿಸಲಾದ ಸಂದೇಶವನ್ನು ಸಂದೇಶಕ್ಕೆ ಲಗತ್ತಿಸಲಾಗಿದೆ (ಸೇರಿಸಿದ ಸಂದೇಶಕ್ಕೆ ಪಾಯಿಂಟರ್ ಅನ್ನು ಮೊದಲ ಸಂದೇಶದಲ್ಲಿ ಹೊಂದಿಸಲಾಗಿದೆ) ಮತ್ತು ಸಂದೇಶವು ಟ್ಯೂಪಲ್ ಆಗಿ ಬದಲಾಗುತ್ತದೆ.

ಟುಪಲ್‌ಗೆ ಡೇಟಾದ ತುಣುಕನ್ನು ಸೇರಿಸುವುದು:

void msgappend(mblk_t *mp, const char *data, size_t size, bool_t pad); 

ಕಾರ್ಯವು appendb() ಅನ್ನು ಲೂಪ್‌ನಲ್ಲಿ ಕರೆಯುತ್ತದೆ.

ಎರಡು ಟುಪಲ್‌ಗಳನ್ನು ಒಂದಾಗಿ ಸಂಯೋಜಿಸುವುದು:

mblk_t *concatb(mblk_t *mp, mblk_t *newm);

ಸಂದೇಶ ಹೊಸ ಗೆ ಲಗತ್ತಿಸಲಾಗುವುದು mp.

ಒಂದೇ ಸಂದೇಶದ ನಕಲನ್ನು ಮಾಡುವುದು:

mblk_t *copyb(const mblk_t *mp);

ಎಲ್ಲಾ ಡೇಟಾ ಬ್ಲಾಕ್‌ಗಳೊಂದಿಗೆ ಟುಪಲ್‌ನ ಸಂಪೂರ್ಣ ನಕಲು:

mblk_t *copymsg(const mblk_t *mp);

ಟ್ಯೂಪಲ್ನ ಅಂಶಗಳನ್ನು ಕಾರ್ಯದಿಂದ ನಕಲಿಸಲಾಗುತ್ತದೆ copyb().

ಸಂದೇಶದ ಸುಲಭ ನಕಲನ್ನು ರಚಿಸಿ mblk_t. ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಡೇಟಾ ಬ್ಲಾಕ್ ಅನ್ನು ನಕಲಿಸಲಾಗಿಲ್ಲ, ಆದರೆ ಅದರ ಉಲ್ಲೇಖ ಕೌಂಟರ್ ಅನ್ನು ಹೆಚ್ಚಿಸಲಾಗಿದೆ db_ref:

mblk_t *dupb(mblk_t *mp);

ಟುಪಲ್‌ನ ಹಗುರವಾದ ನಕಲನ್ನು ತಯಾರಿಸುವುದು. ಡೇಟಾ ಬ್ಲಾಕ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗಿಲ್ಲ, ಅವುಗಳ ಉಲ್ಲೇಖ ಕೌಂಟರ್‌ಗಳನ್ನು ಮಾತ್ರ ಹೆಚ್ಚಿಸಲಾಗುತ್ತದೆ db_ref:

mblk_t *dupmsg(mblk_t* m);

ಟುಪಲ್‌ನ ಎಲ್ಲಾ ಸಂದೇಶಗಳನ್ನು ಒಂದು ಸಂದೇಶದಲ್ಲಿ ಅಂಟಿಸುವುದು:

void msgpullup(mblk_t *mp,size_t len);

ವಾದದ ವೇಳೆ ಲೆನ್ -1 ಆಗಿದೆ, ನಂತರ ಹಂಚಲಾದ ಬಫರ್‌ನ ಗಾತ್ರವನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿರ್ಧರಿಸಲಾಗುತ್ತದೆ.

ಸಂದೇಶವನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ, ಟುಪಲ್:

void freemsg(mblk_t *mp);

ಡೇಟಾ ಬ್ಲಾಕ್‌ನ ಉಲ್ಲೇಖದ ಸಂಖ್ಯೆಯನ್ನು ಒಂದರಿಂದ ಕಡಿಮೆ ಮಾಡಲಾಗಿದೆ. ಅದು ಶೂನ್ಯವನ್ನು ತಲುಪಿದರೆ, ಡೇಟಾ ಬ್ಲಾಕ್ ಅನ್ನು ಸಹ ಅಳಿಸಲಾಗುತ್ತದೆ.

ಸಂದೇಶ ಅಥವಾ ಟುಪಲ್‌ನಲ್ಲಿನ ಒಟ್ಟು ಡೇಟಾದ ಲೆಕ್ಕಾಚಾರ.

size_t msgdsize(const mblk_t *mp);

ಸರದಿಯ ಬಾಲದಿಂದ ಸಂದೇಶವನ್ನು ಹಿಂಪಡೆಯಲಾಗುತ್ತಿದೆ:

mblk_t *ms_queue_peek_last (q);

ಒಂದು ಸಂದೇಶದ ಕಾಯ್ದಿರಿಸಿದ ಕ್ಷೇತ್ರಗಳ ವಿಷಯಗಳನ್ನು ಮತ್ತೊಂದು ಸಂದೇಶಕ್ಕೆ ನಕಲಿಸುವುದು (ವಾಸ್ತವವಾಗಿ, ಈ ಕ್ಷೇತ್ರಗಳು ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್ ಬಳಸುವ ಫ್ಲ್ಯಾಗ್‌ಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತವೆ):

mblk_meta_copy(const mblk_t *source, mblk *dest);

ಕ್ಯೂ ಕ್ಯೂ_ಟಿ

ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್‌ನಲ್ಲಿನ ಸಂದೇಶ ಸರದಿಯನ್ನು ವೃತ್ತಾಕಾರದ ಡಬಲ್ಲಿ ಲಿಂಕ್ ಪಟ್ಟಿಯಂತೆ ಅಳವಡಿಸಲಾಗಿದೆ. ಪ್ರತಿಯೊಂದು ಪಟ್ಟಿಯ ಅಂಶವು ಸಿಗ್ನಲ್ ಮಾದರಿಗಳೊಂದಿಗೆ ಡೇಟಾ ಬ್ಲಾಕ್ಗೆ ಪಾಯಿಂಟರ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಡೇಟಾ ಬ್ಲಾಕ್‌ಗೆ ಪಾಯಿಂಟರ್‌ಗಳು ಮಾತ್ರ ಪ್ರತಿಯಾಗಿ ಚಲಿಸುತ್ತವೆ ಎಂದು ಅದು ತಿರುಗುತ್ತದೆ, ಆದರೆ ಡೇಟಾವು ಚಲನರಹಿತವಾಗಿರುತ್ತದೆ. ಆ. ಅವರಿಗೆ ಲಿಂಕ್‌ಗಳನ್ನು ಮಾತ್ರ ಸರಿಸಲಾಗಿದೆ.
ಸರದಿಯನ್ನು ವಿವರಿಸುವ ರಚನೆ ಕ್ಯೂ_ಟಿ, ಕೆಳಗೆ ತೋರಿಸಲಾಗಿದೆ:

typedef struct _queue
{
   mblk_t _q_stopper; /* "Холостой" элемент очереди, не указывает на данные, используется только для управления очередью. При инициализации очереди (qinit()) его указатели настраиваются так, чтобы они указывали на него самого. */
   int q_mcount;        // Количество элементов в очереди.
} queue_t;

ರಚನೆಯು ಕ್ಷೇತ್ರವನ್ನು ಹೊಂದಿದೆ - ಪಾಯಿಂಟರ್ _q_ಸ್ಟಾಪರ್ *mblk_t ಎಂದು ಟೈಪ್ ಮಾಡಿ, ಇದು ಸರದಿಯಲ್ಲಿರುವ ಮೊದಲ ಅಂಶವನ್ನು (ಸಂದೇಶ) ಸೂಚಿಸುತ್ತದೆ. ರಚನೆಯ ಎರಡನೇ ಕ್ಷೇತ್ರವು ಸರದಿಯಲ್ಲಿರುವ ಸಂದೇಶಗಳ ಕೌಂಟರ್ ಆಗಿದೆ.
ಕೆಳಗಿನ ಚಿತ್ರವು 1 ಸಂದೇಶಗಳನ್ನು ಹೊಂದಿರುವ q4 ಹೆಸರಿನ ಸರದಿಯನ್ನು ತೋರಿಸುತ್ತದೆ m1, m2, m3, m4.
Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 11
ಕೆಳಗಿನ ಚಿತ್ರವು q1 ಹೆಸರಿನ ಕ್ಯೂ ಅನ್ನು ತೋರಿಸುತ್ತದೆ, ಇದರಲ್ಲಿ 4 ಸಂದೇಶಗಳು m1,m2,m3,m4. ಸಂದೇಶ m2 ಎಂಬುದು tuple ನ ಹೆಡ್ ಆಗಿದ್ದು ಅದು m2_1 ಮತ್ತು m2_2 ಎಂಬ ಎರಡು ಸಂದೇಶಗಳನ್ನು ಒಳಗೊಂಡಿದೆ.

Mediastreamer2 VoIP ಎಂಜಿನ್ ಅನ್ನು ಅನ್ವೇಷಿಸಲಾಗುತ್ತಿದೆ. ಭಾಗ 11

ಕ್ಯೂಗಳು ಕ್ಯೂ_ಟಿಯೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವ ಕಾರ್ಯಗಳು

ಸರದಿ ಆರಂಭ:

void qinit(queue_t *q);

ಕ್ಷೇತ್ರ _q_ಸ್ಟಾಪರ್ (ಇನ್ನು ಮುಂದೆ ನಾವು ಅದನ್ನು "ಸ್ಟಾಪರ್" ಎಂದು ಕರೆಯುತ್ತೇವೆ) ಕಾರ್ಯದಿಂದ ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ mblk_init(), ಅದರ ಹಿಂದಿನ ಅಂಶ ಮತ್ತು ಮುಂದಿನ ಅಂಶ ಪಾಯಿಂಟರ್ ಅನ್ನು ಸ್ವತಃ ಸೂಚಿಸಲು ಹೊಂದಿಸಲಾಗಿದೆ. ಸರದಿ ಅಂಶ ಕೌಂಟರ್ ಅನ್ನು ಶೂನ್ಯಕ್ಕೆ ಮರುಹೊಂದಿಸಲಾಗಿದೆ.

ಹೊಸ ಅಂಶವನ್ನು ಸೇರಿಸಲಾಗುತ್ತಿದೆ (ಸಂದೇಶಗಳು):

void putq(queue_t *q, mblk_t *m);

ಹೊಸ ಅಂಶ m ಪಟ್ಟಿಯ ಅಂತ್ಯಕ್ಕೆ ಸೇರಿಸಲಾಗುತ್ತದೆ, ಅಂಶ ಪಾಯಿಂಟರ್‌ಗಳನ್ನು ಸರಿಹೊಂದಿಸಲಾಗುತ್ತದೆ ಇದರಿಂದ ಸ್ಟಾಪರ್ ಅದರ ಮುಂದಿನ ಅಂಶವಾಗುತ್ತದೆ ಮತ್ತು ಇದು ಸ್ಟಾಪರ್‌ಗೆ ಹಿಂದಿನ ಅಂಶವಾಗುತ್ತದೆ. ಸರದಿ ಅಂಶ ಕೌಂಟರ್ ಅನ್ನು ಹೆಚ್ಚಿಸಲಾಗಿದೆ.

ಸರದಿಯಿಂದ ಒಂದು ಅಂಶವನ್ನು ಹಿಂಪಡೆಯಲಾಗುತ್ತಿದೆ:

mblk_t * getq(queue_t *q); 

ಸ್ಟಾಪರ್ ನಂತರ ಬರುವ ಸಂದೇಶವನ್ನು ಹಿಂಪಡೆಯಲಾಗುತ್ತದೆ ಮತ್ತು ಅಂಶ ಕೌಂಟರ್ ಅನ್ನು ಕಡಿಮೆಗೊಳಿಸಲಾಗುತ್ತದೆ. ಸ್ಟಾಪರ್ ಹೊರತುಪಡಿಸಿ ಸರದಿಯಲ್ಲಿ ಯಾವುದೇ ಅಂಶಗಳಿಲ್ಲದಿದ್ದರೆ, ನಂತರ 0 ಅನ್ನು ಹಿಂತಿರುಗಿಸಲಾಗುತ್ತದೆ.

ಸರದಿ ಸಾಲಿನಲ್ಲಿ ಸಂದೇಶವನ್ನು ಸೇರಿಸುವುದು:

void insq(queue_t *q, mblk_t *emp, mblk_t *mp); 

ಎಲಿಮೆಂಟ್ mp ಅಂಶದ ಮೊದಲು ಸೇರಿಸಲಾಗಿದೆ ಕಂಪನ. ವೇಳೆ ಕಂಪನ=0, ನಂತರ ಸಂದೇಶವನ್ನು ಸರದಿಯ ಬಾಲಕ್ಕೆ ಸೇರಿಸಲಾಗುತ್ತದೆ.

ಸರದಿಯ ಮುಖ್ಯಸ್ಥರಿಂದ ಸಂದೇಶವನ್ನು ಹಿಂಪಡೆಯಲಾಗುತ್ತಿದೆ:

void remq(queue_t *q, mblk_t *mp); 

ಅಂಶ ಕೌಂಟರ್ ಕಡಿಮೆಯಾಗಿದೆ.

ಸರದಿಯಲ್ಲಿನ ಮೊದಲ ಅಂಶಕ್ಕೆ ಪಾಯಿಂಟರ್ ಅನ್ನು ಓದುವುದು:

mblk_t * peekq(queue_t *q); 

ಅಂಶಗಳನ್ನು ಅಳಿಸುವಾಗ ಎಲ್ಲಾ ಅಂಶಗಳನ್ನು ಸರದಿಯಿಂದ ತೆಗೆದುಹಾಕುವುದು:

void flushq(queue_t *q, int how);

ವಾದ ಹೇಗೆ ಬಳಸಲಾಗುವುದಿಲ್ಲ. ಸರದಿ ಅಂಶದ ಕೌಂಟರ್ ಅನ್ನು ಶೂನ್ಯಕ್ಕೆ ಹೊಂದಿಸಲಾಗಿದೆ.

ಸರದಿಯ ಕೊನೆಯ ಅಂಶಕ್ಕೆ ಪಾಯಿಂಟರ್ ಅನ್ನು ಓದಲು ಮ್ಯಾಕ್ರೋ:

mblk_t * qlast(queue_t *q);

ಸಂದೇಶದ ಸಾಲುಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ, ನೀವು ಕರೆ ಮಾಡಿದಾಗ ತಿಳಿದಿರಲಿ ms_queue_put(q, m) ಸಂದೇಶಕ್ಕೆ ಶೂನ್ಯ ಪಾಯಿಂಟರ್‌ನೊಂದಿಗೆ, ಕಾರ್ಯವು ಲೂಪ್ ಆಗುತ್ತದೆ. ನಿಮ್ಮ ಪ್ರೋಗ್ರಾಂ ಫ್ರೀಜ್ ಆಗುತ್ತದೆ. ಅದೇ ರೀತಿ ವರ್ತಿಸುತ್ತದೆ ms_queue_ಮುಂದೆ(q, m).

ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ

ಮೇಲೆ ವಿವರಿಸಿದ ಸರದಿಯನ್ನು ಒಂದು ಫಿಲ್ಟರ್‌ನಿಂದ ಇನ್ನೊಂದಕ್ಕೆ ಅಥವಾ ಒಂದರಿಂದ ಹಲವಾರು ಫಿಲ್ಟರ್‌ಗಳಿಗೆ ಸಂದೇಶಗಳನ್ನು ರವಾನಿಸಲು ಬಳಸಲಾಗುತ್ತದೆ. ಶೋಧಕಗಳು ಮತ್ತು ಅವುಗಳ ಸಂಪರ್ಕಗಳು ನಿರ್ದೇಶಿತ ಗ್ರಾಫ್ ಅನ್ನು ರೂಪಿಸುತ್ತವೆ. ಫಿಲ್ಟರ್ನ ಇನ್ಪುಟ್ ಅಥವಾ ಔಟ್ಪುಟ್ ಅನ್ನು ಸಾಮಾನ್ಯ ಪದ "ಪಿನ್" ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ. ಫಿಲ್ಟರ್‌ಗಳು ಪರಸ್ಪರ ಸಂಪರ್ಕಗೊಂಡಿರುವ ಕ್ರಮವನ್ನು ವಿವರಿಸಲು, ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್ "ಸಿಗ್ನಲ್ ಪಾಯಿಂಟ್" ಪರಿಕಲ್ಪನೆಯನ್ನು ಬಳಸುತ್ತದೆ. ಸಿಗ್ನಲ್ ಪಾಯಿಂಟ್ ರಚನೆಯಾಗಿದೆ _MSCP ಪಾಯಿಂಟ್, ಇದು ಫಿಲ್ಟರ್‌ಗೆ ಪಾಯಿಂಟರ್ ಮತ್ತು ಅದರ ಒಂದು ಪಿನ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ; ಅದರ ಪ್ರಕಾರ, ಇದು ಫಿಲ್ಟರ್‌ನ ಒಳಹರಿವು ಅಥವಾ ಔಟ್‌ಪುಟ್‌ಗಳ ಸಂಪರ್ಕವನ್ನು ವಿವರಿಸುತ್ತದೆ.

ಡೇಟಾ ಸಂಸ್ಕರಣಾ ಗ್ರಾಫ್ನ ಸಿಗ್ನಲ್ ಪಾಯಿಂಟ್

typedef struct _MSCPoint{
struct _MSFilter *filter; // Указатель на фильтр медиастримера.
int pin;                        // Номер одного из входов или выходов фильтра, т.е. пин.
} MSCPoint;

ಫಿಲ್ಟರ್ ಪಿನ್‌ಗಳು ಶೂನ್ಯದಿಂದ ಪ್ರಾರಂಭವಾಗುತ್ತವೆ.

ಸಂದೇಶ ಸರದಿಯ ಮೂಲಕ ಎರಡು ಪಿನ್‌ಗಳ ಸಂಪರ್ಕವನ್ನು ರಚನೆಯಿಂದ ವಿವರಿಸಲಾಗಿದೆ _ಎಂಎಸ್ ಕ್ಯೂ, ಇದು ಸಂಪರ್ಕಿಸುವ ಎರಡು ಸಿಗ್ನಲ್ ಪಾಯಿಂಟ್‌ಗಳಿಗೆ ಸಂದೇಶ ಕ್ಯೂ ಮತ್ತು ಪಾಯಿಂಟರ್‌ಗಳನ್ನು ಒಳಗೊಂಡಿದೆ:

typedef struct _MSQueue
{
queue_t q;
MSCPoint prev;
MSCPoint next;
}MSQueue;

ನಾವು ಈ ರಚನೆಯನ್ನು ಸಿಗ್ನಲ್ ಲಿಂಕ್ ಎಂದು ಕರೆಯುತ್ತೇವೆ. ಪ್ರತಿ ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮರ್ ಫಿಲ್ಟರ್ ಇನ್‌ಪುಟ್ ಲಿಂಕ್‌ಗಳ ಟೇಬಲ್ ಮತ್ತು ಔಟ್‌ಪುಟ್ ಲಿಂಕ್‌ಗಳ ಟೇಬಲ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ (MSQueue) ಫಿಲ್ಟರ್ ರಚಿಸುವಾಗ ಕೋಷ್ಟಕಗಳ ಗಾತ್ರವನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ; ನಾವು ಈಗಾಗಲೇ ರಫ್ತು ಮಾಡಲಾದ ಪ್ರಕಾರದ ವೇರಿಯಬಲ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಇದನ್ನು ಮಾಡಿದ್ದೇವೆ MSFilterDesc, ನಾವು ನಮ್ಮ ಸ್ವಂತ ಫಿಲ್ಟರ್ ಅನ್ನು ಅಭಿವೃದ್ಧಿಪಡಿಸಿದಾಗ. ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮರ್‌ನಲ್ಲಿ ಯಾವುದೇ ಫಿಲ್ಟರ್ ಅನ್ನು ವಿವರಿಸುವ ರಚನೆಯನ್ನು ಕೆಳಗೆ ನೀಡಲಾಗಿದೆ, MSFilter:


struct _MSFilter{
    MSFilterDesc *desc;    /* Указатель на дескриптор фильтра. */
    /* Защищенные атрибуты, их нельзя сдвигать или убирать иначе будет нарушена работа с плагинами. */
    ms_mutex_t lock;      /* Семафор. */
    MSQueue **inputs;     /* Таблица входных линков. */
    MSQueue **outputs;    /* Таблица выходных линков. */
    struct _MSFactory *factory; /* Указатель на фабрику, которая создала данный экземпляр фильтра. */
    void *padding;              /* Не используется, будет задействован если добавятся защищенные поля. */
    void *data;                 /* Указатель на произвольную структуру для хранения данных внутреннего состояния фильтра и промежуточных вычислений. */
    struct _MSTicker *ticker;   /* Указатель на объект тикера, который не должен быть нулевым когда вызывается функция process(). */
    /*private attributes, they can be moved and changed at any time*/
    MSList *notify_callbacks; /* Список обратных вызовов, используемых для обработки событий фильтра. */
    uint32_t last_tick;       /* Номер последнего такта, когда выполнялся вызов process(). */ 
    MSFilterStats *stats;     /* Статистика работы фильтра.*/
    int postponed_task; /*Количество отложенных задач. Некоторые фильтры могут откладывать обработку данных (вызов process()) на несколько тактов.*/
    bool_t seen;  /* Флаг, который использует тикер, чтобы помечать что этот экземпляр фильтра он уже обслужил на данном такте.*/
};
typedef struct _MSFilter MSFilter;

ನಮ್ಮ ಯೋಜನೆಗೆ ಅನುಗುಣವಾಗಿ ನಾವು ಸಿ ಪ್ರೋಗ್ರಾಂನಲ್ಲಿ ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಸಂಪರ್ಕಿಸಿದ ನಂತರ (ಆದರೆ ಟಿಕ್ಕರ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಲಿಲ್ಲ), ನಾವು ಆ ಮೂಲಕ ನಿರ್ದೇಶಿತ ಗ್ರಾಫ್ ಅನ್ನು ರಚಿಸಿದ್ದೇವೆ, ಅದರ ನೋಡ್‌ಗಳು ರಚನೆಯ ನಿದರ್ಶನಗಳಾಗಿವೆ MSFilter, ಮತ್ತು ಅಂಚುಗಳು ಲಿಂಕ್‌ಗಳ ನಿದರ್ಶನಗಳಾಗಿವೆ MSQueue.

ಟಿಕ್ಕರ್‌ನ ತೆರೆಮರೆಯ ಚಟುವಟಿಕೆಗಳು

ಉಣ್ಣಿಗಳ ಮೂಲಕ್ಕೆ ಟಿಕ್ಕರ್ ಫಿಲ್ಟರ್ ಎಂದು ನಾನು ನಿಮಗೆ ಹೇಳಿದಾಗ, ಅದು ಅದರ ಬಗ್ಗೆ ಸಂಪೂರ್ಣ ಸತ್ಯವಲ್ಲ. ಟಿಕ್ಕರ್ ಎನ್ನುವುದು ಗಡಿಯಾರದಲ್ಲಿ ಕಾರ್ಯಗಳನ್ನು ನಡೆಸುವ ವಸ್ತುವಾಗಿದೆ ಪ್ರಕ್ರಿಯೆ() ಇದು ಸಂಪರ್ಕಗೊಂಡಿರುವ ಸರ್ಕ್ಯೂಟ್ (ಗ್ರಾಫ್) ನ ಎಲ್ಲಾ ಫಿಲ್ಟರ್‌ಗಳು. ನಾವು ಸಿ ಪ್ರೋಗ್ರಾಂನಲ್ಲಿ ಗ್ರಾಫ್ ಫಿಲ್ಟರ್‌ಗೆ ಟಿಕ್ಕರ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಿದಾಗ, ನಾವು ಅದನ್ನು ಆಫ್ ಮಾಡುವವರೆಗೆ ಅದು ನಿಯಂತ್ರಿಸುವ ಗ್ರಾಫ್ ಅನ್ನು ನಾವು ಟಿಕರ್‌ಗೆ ತೋರಿಸುತ್ತೇವೆ. ಸಂಪರ್ಕಿಸಿದ ನಂತರ, ಟಿಕ್ಕರ್ ಅದರ ಆರೈಕೆಗೆ ಒಪ್ಪಿಸಲಾದ ಗ್ರಾಫ್ ಅನ್ನು ಪರೀಕ್ಷಿಸಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ, ಅದನ್ನು ಒಳಗೊಂಡಿರುವ ಫಿಲ್ಟರ್ಗಳ ಪಟ್ಟಿಯನ್ನು ಕಂಪೈಲ್ ಮಾಡುತ್ತದೆ. ಒಂದೇ ಫಿಲ್ಟರ್ ಅನ್ನು ಎರಡು ಬಾರಿ "ಎಣಿಕೆ" ಮಾಡದಿರಲು, ಇದು ಪತ್ತೆಯಾದ ಫಿಲ್ಟರ್‌ಗಳಲ್ಲಿ ಚೆಕ್‌ಬಾಕ್ಸ್ ಅನ್ನು ಇರಿಸುವ ಮೂಲಕ ಗುರುತಿಸುತ್ತದೆ ಕಾಣಬಹುದು. ಪ್ರತಿ ಫಿಲ್ಟರ್ ಹೊಂದಿರುವ ಲಿಂಕ್ ಕೋಷ್ಟಕಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಹುಡುಕಾಟವನ್ನು ಕೈಗೊಳ್ಳಲಾಗುತ್ತದೆ.

ಗ್ರಾಫ್‌ನ ಪರಿಚಯಾತ್ಮಕ ಪ್ರವಾಸದ ಸಮಯದಲ್ಲಿ, ಫಿಲ್ಟರ್‌ಗಳಲ್ಲಿ ಡೇಟಾ ಬ್ಲಾಕ್‌ಗಳ ಮೂಲವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ಕನಿಷ್ಠ ಒಂದಾದರೂ ಇದೆಯೇ ಎಂದು ಟಿಕ್ಕರ್ ಪರಿಶೀಲಿಸುತ್ತದೆ. ಯಾವುದೂ ಇಲ್ಲದಿದ್ದರೆ, ಗ್ರಾಫ್ ಅನ್ನು ತಪ್ಪಾಗಿ ಪರಿಗಣಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಟಿಕ್ಕರ್ ಕ್ರ್ಯಾಶ್ ಆಗುತ್ತದೆ.

ಗ್ರಾಫ್ "ಸರಿಯಾದ" ಎಂದು ತಿರುಗಿದರೆ, ಪ್ರತಿ ಕಂಡುಬರುವ ಫಿಲ್ಟರ್ಗೆ, ಕಾರ್ಯವನ್ನು ಪ್ರಾರಂಭಿಸಲು ಕರೆಯಲಾಗುತ್ತದೆ ಪೂರ್ವ ಪ್ರಕ್ರಿಯೆ(). ಮುಂದಿನ ಸಂಸ್ಕರಣಾ ಚಕ್ರಕ್ಕೆ ಕ್ಷಣ ಬಂದ ತಕ್ಷಣ (ಡೀಫಾಲ್ಟ್ ಆಗಿ ಪ್ರತಿ 10 ಮಿಲಿಸೆಕೆಂಡುಗಳು), ಟಿಕ್ಕರ್ ಕಾರ್ಯವನ್ನು ಕರೆಯುತ್ತದೆ ಪ್ರಕ್ರಿಯೆ() ಹಿಂದೆ ಪತ್ತೆಯಾದ ಎಲ್ಲಾ ಮೂಲ ಫಿಲ್ಟರ್‌ಗಳಿಗೆ ಮತ್ತು ನಂತರ ಪಟ್ಟಿಯಲ್ಲಿ ಉಳಿದಿರುವ ಫಿಲ್ಟರ್‌ಗಳಿಗೆ. ಫಿಲ್ಟರ್ ಇನ್‌ಪುಟ್ ಲಿಂಕ್‌ಗಳನ್ನು ಹೊಂದಿದ್ದರೆ, ನಂತರ ಕಾರ್ಯವನ್ನು ರನ್ ಮಾಡುತ್ತದೆ ಪ್ರಕ್ರಿಯೆ() ಇನ್‌ಪುಟ್ ಲಿಂಕ್ ಕ್ಯೂಗಳು ಖಾಲಿಯಾಗುವವರೆಗೆ ಪುನರಾವರ್ತಿಸುತ್ತದೆ. ಇದರ ನಂತರ, ಇದು ಪಟ್ಟಿಯಲ್ಲಿರುವ ಮುಂದಿನ ಫಿಲ್ಟರ್‌ಗೆ ಚಲಿಸುತ್ತದೆ ಮತ್ತು ಇನ್‌ಪುಟ್ ಲಿಂಕ್‌ಗಳು ಸಂದೇಶಗಳಿಂದ ಮುಕ್ತವಾಗುವವರೆಗೆ ಅದನ್ನು "ಸ್ಕ್ರಾಲ್ ಮಾಡುತ್ತದೆ". ಪಟ್ಟಿ ಮುಗಿಯುವವರೆಗೆ ಟಿಕ್ಕರ್ ಫಿಲ್ಟರ್‌ನಿಂದ ಫಿಲ್ಟರ್‌ಗೆ ಚಲಿಸುತ್ತದೆ. ಇದು ಚಕ್ರದ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸುತ್ತದೆ.

ಈಗ ನಾವು ಟುಪಲ್ಸ್‌ಗೆ ಹಿಂತಿರುಗುತ್ತೇವೆ ಮತ್ತು ಅಂತಹ ಘಟಕವನ್ನು ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್‌ಗೆ ಏಕೆ ಸೇರಿಸಲಾಗಿದೆ ಎಂಬುದರ ಕುರಿತು ಮಾತನಾಡುತ್ತೇವೆ. ಸಾಮಾನ್ಯವಾಗಿ, ಫಿಲ್ಟರ್ ಒಳಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ಅಲ್ಗಾರಿದಮ್‌ಗೆ ಅಗತ್ಯವಿರುವ ಡೇಟಾದ ಪ್ರಮಾಣವು ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ ಮತ್ತು ಇನ್‌ಪುಟ್‌ನಲ್ಲಿ ಸ್ವೀಕರಿಸಿದ ಡೇಟಾ ಬಫರ್‌ಗಳ ಗಾತ್ರದ ಬಹುಸಂಖ್ಯೆಯಲ್ಲ. ಉದಾಹರಣೆಗೆ, ನಾವು ವೇಗದ ಫೋರಿಯರ್ ರೂಪಾಂತರವನ್ನು ನಿರ್ವಹಿಸುವ ಫಿಲ್ಟರ್ ಅನ್ನು ಬರೆಯುತ್ತಿದ್ದೇವೆ, ಇದು ವ್ಯಾಖ್ಯಾನದ ಪ್ರಕಾರ ಎರಡು ಶಕ್ತಿಯಿರುವ ಡೇಟಾ ಬ್ಲಾಕ್ಗಳನ್ನು ಮಾತ್ರ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಬಹುದು. ಇದು 512 ಎಣಿಕೆಗಳಾಗಿರಲಿ. ಟೆಲಿಫೋನ್ ಚಾನಲ್‌ನಿಂದ ಡೇಟಾವನ್ನು ರಚಿಸಿದರೆ, ಇನ್‌ಪುಟ್‌ನಲ್ಲಿರುವ ಪ್ರತಿ ಸಂದೇಶದ ಡೇಟಾ ಬಫರ್ ನಮಗೆ 160 ಸಿಗ್ನಲ್ ಮಾದರಿಗಳನ್ನು ತರುತ್ತದೆ. ಅಗತ್ಯವಿರುವ ಪ್ರಮಾಣದ ಡೇಟಾ ಇರುವವರೆಗೆ ಇನ್‌ಪುಟ್‌ನಿಂದ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸದಿರಲು ಇದು ಪ್ರಚೋದಿಸುತ್ತದೆ. ಆದರೆ ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಟಿಕ್ಕರ್ನೊಂದಿಗೆ ಘರ್ಷಣೆ ಸಂಭವಿಸುತ್ತದೆ, ಇದು ಇನ್ಪುಟ್ ಲಿಂಕ್ ಖಾಲಿಯಾಗುವವರೆಗೆ ಫಿಲ್ಟರ್ ಅನ್ನು ಸ್ಕ್ರಾಲ್ ಮಾಡಲು ವಿಫಲಗೊಳ್ಳುತ್ತದೆ. ಹಿಂದೆ, ನಾವು ಈ ನಿಯಮವನ್ನು ಫಿಲ್ಟರ್‌ನ ಮೂರನೇ ತತ್ವವೆಂದು ಗೊತ್ತುಪಡಿಸಿದ್ದೇವೆ. ಈ ತತ್ವದ ಪ್ರಕಾರ, ಫಿಲ್ಟರ್‌ನ ಪ್ರಕ್ರಿಯೆ() ಕಾರ್ಯವು ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಇನ್‌ಪುಟ್ ಕ್ಯೂಗಳಿಂದ ತೆಗೆದುಕೊಳ್ಳಬೇಕು.

ಹೆಚ್ಚುವರಿಯಾಗಿ, ಇನ್ಪುಟ್ನಿಂದ ಕೇವಲ 512 ಮಾದರಿಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ, ಏಕೆಂದರೆ ನೀವು ಸಂಪೂರ್ಣ ಬ್ಲಾಕ್ಗಳನ್ನು ಮಾತ್ರ ತೆಗೆದುಕೊಳ್ಳಬಹುದು, ಅಂದರೆ. ಫಿಲ್ಟರ್ 640 ಮಾದರಿಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಬೇಕು ಮತ್ತು ಅವುಗಳಲ್ಲಿ 512 ಅನ್ನು ಬಳಸಬೇಕಾಗುತ್ತದೆ, ಉಳಿದವು ಡೇಟಾದ ಹೊಸ ಭಾಗವನ್ನು ಸಂಗ್ರಹಿಸುವ ಮೊದಲು. ಹೀಗಾಗಿ, ನಮ್ಮ ಫಿಲ್ಟರ್, ಅದರ ಮುಖ್ಯ ಕೆಲಸದ ಜೊತೆಗೆ, ಇನ್ಪುಟ್ ಡೇಟಾದ ಮಧ್ಯಂತರ ಸಂಗ್ರಹಣೆಗಾಗಿ ಸಹಾಯಕ ಕ್ರಮಗಳನ್ನು ಒದಗಿಸಬೇಕು. ಈ ಸಾಮಾನ್ಯ ಸಮಸ್ಯೆಗೆ ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮರ್ ಮತ್ತು ಪರಿಹಾರದ ಡೆವಲಪರ್‌ಗಳು ವಿಶೇಷ ವಸ್ತುವನ್ನು ಅಭಿವೃದ್ಧಿಪಡಿಸಿದ್ದಾರೆ - MSBufferizer (ಬಫರರ್), ಇದು tuples ಅನ್ನು ಬಳಸಿಕೊಂಡು ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸುತ್ತದೆ.

ಬಫರೈಸರ್ (MSBufferizer)

ಇದು ಫಿಲ್ಟರ್ ಒಳಗೆ ಇನ್‌ಪುಟ್ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸುವ ವಸ್ತುವಾಗಿದೆ ಮತ್ತು ಫಿಲ್ಟರ್ ಅಲ್ಗಾರಿದಮ್ ಅನ್ನು ಚಲಾಯಿಸಲು ಮಾಹಿತಿಯ ಪ್ರಮಾಣವು ಸಾಕಾಗುವಷ್ಟು ಬೇಗ ಅದನ್ನು ಪ್ರಕ್ರಿಯೆಗೆ ಸಲ್ಲಿಸಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ. ಬಫರ್ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸುತ್ತಿರುವಾಗ, ಪ್ರೊಸೆಸರ್‌ನ ಸಂಸ್ಕರಣಾ ಶಕ್ತಿಯನ್ನು ಬಳಸದೆಯೇ ಫಿಲ್ಟರ್ ಐಡಲ್ ಮೋಡ್‌ನಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ಆದರೆ ಬಫರರ್‌ನಿಂದ ಓದುವ ಕಾರ್ಯವು ಶೂನ್ಯಕ್ಕಿಂತ ಬೇರೆ ಮೌಲ್ಯವನ್ನು ಹಿಂದಿರುಗಿಸಿದ ತಕ್ಷಣ, ಫಿಲ್ಟರ್‌ನ ಪ್ರಕ್ರಿಯೆ() ಕಾರ್ಯವು ಬಫರರ್‌ನಿಂದ ಅಗತ್ಯವಿರುವ ಗಾತ್ರದ ಭಾಗಗಳಲ್ಲಿ ಡೇಟಾವನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ಮತ್ತು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ, ಅದು ಖಾಲಿಯಾಗುವವರೆಗೆ.
ಇನ್ನೂ ಅಗತ್ಯವಿಲ್ಲದ ಡೇಟಾವು ಟುಪಲ್‌ನ ಮೊದಲ ಅಂಶವಾಗಿ ಬಫರ್‌ನಲ್ಲಿ ಉಳಿದಿದೆ, ಅದರ ನಂತರದ ಇನ್‌ಪುಟ್ ಡೇಟಾದ ಬ್ಲಾಕ್‌ಗಳನ್ನು ಲಗತ್ತಿಸಲಾಗಿದೆ.

ಬಫರ್ ಅನ್ನು ವಿವರಿಸುವ ರಚನೆ:

struct _MSBufferizer{
queue_t q; /* Очередь сообщений. */
int size; /* Суммарный размер данных находящихся в буферизаторе в данный момент. */
};
typedef struct _MSBufferizer MSBufferizer;

MSBufferizer ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವ ಕಾರ್ಯಗಳು

ಹೊಸ ಬಫರ್ ನಿದರ್ಶನವನ್ನು ರಚಿಸಲಾಗುತ್ತಿದೆ:

MSBufferizer * ms_bufferizer_new(void);

ಮೆಮೊರಿಯನ್ನು ನಿಯೋಜಿಸಲಾಗಿದೆ, ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ ms_bufferizer_init() ಮತ್ತು ಪಾಯಿಂಟರ್ ಅನ್ನು ಹಿಂತಿರುಗಿಸಲಾಗುತ್ತದೆ.

ಪ್ರಾರಂಭಿಕ ಕಾರ್ಯ:

void ms_bufferizer_init(MSBufferizer *obj); 

ಸರದಿಯನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ q, ಕ್ಷೇತ್ರ ಗಾತ್ರ ಶೂನ್ಯಕ್ಕೆ ಹೊಂದಿಸಲಾಗಿದೆ.

ಸಂದೇಶವನ್ನು ಸೇರಿಸಲಾಗುತ್ತಿದೆ:

void ms_bufferizer_put(MSBufferizer *obj, mblk_t *m); 

ಸಂದೇಶ m ಅನ್ನು ಸರದಿಯಲ್ಲಿ ಸೇರಿಸಲಾಗಿದೆ. ಡೇಟಾ ಬ್ಲಾಕ್‌ಗಳ ಲೆಕ್ಕಾಚಾರದ ಗಾತ್ರವನ್ನು ಸೇರಿಸಲಾಗುತ್ತದೆ ಗಾತ್ರ.

ಎಲ್ಲಾ ಸಂದೇಶಗಳನ್ನು ಲಿಂಕ್ ಡೇಟಾ ಸರದಿಯಿಂದ ಬಫರ್‌ಗೆ ವರ್ಗಾಯಿಸಲಾಗುತ್ತಿದೆ q:

void ms_bufferizer_put_from_queue(MSBufferizer *obj, MSQueue *q);   

ಲಿಂಕ್‌ನಿಂದ ಸಂದೇಶಗಳನ್ನು ವರ್ಗಾಯಿಸಲಾಗುತ್ತಿದೆ q ಬಫರ್ನಲ್ಲಿ ಕಾರ್ಯವನ್ನು ಬಳಸಿಕೊಂಡು ನಿರ್ವಹಿಸಲಾಗುತ್ತದೆ ms_bufferizer_put().

ಬಫರ್‌ನಿಂದ ಓದುವುದು:

int ms_bufferizer_read(MSBufferizer *obj, uint8_t *data, int datalen); 

ಬಫರ್‌ನಲ್ಲಿ ಸಂಗ್ರಹವಾದ ಡೇಟಾದ ಗಾತ್ರವು ವಿನಂತಿಸಿದ ಒಂದಕ್ಕಿಂತ ಕಡಿಮೆಯಿದ್ದರೆ (ಡಾಟಾಲೆನ್), ನಂತರ ಕಾರ್ಯವು ಶೂನ್ಯವನ್ನು ಹಿಂದಿರುಗಿಸುತ್ತದೆ, ಡೇಟಾವನ್ನು ಡೇಟಾಗೆ ನಕಲಿಸಲಾಗುವುದಿಲ್ಲ. ಇಲ್ಲದಿದ್ದರೆ, ಬಫರ್‌ನಲ್ಲಿರುವ ಟುಪಲ್‌ಗಳಿಂದ ಡೇಟಾದ ಅನುಕ್ರಮ ನಕಲು ಮಾಡಲಾಗುತ್ತದೆ. ನಕಲು ಮಾಡಿದ ನಂತರ, ಟುಪಲ್ ಅನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಮೆಮೊರಿಯನ್ನು ಮುಕ್ತಗೊಳಿಸಲಾಗುತ್ತದೆ. ಡೇಟಾಲೆನ್ ಬೈಟ್‌ಗಳನ್ನು ನಕಲಿಸುವ ಕ್ಷಣದಲ್ಲಿ ನಕಲಿಸುವುದು ಕೊನೆಗೊಳ್ಳುತ್ತದೆ. ಡೇಟಾ ಬ್ಲಾಕ್‌ನ ಮಧ್ಯದಲ್ಲಿ ಸ್ಥಳವು ಖಾಲಿಯಾದರೆ, ಈ ಸಂದೇಶದಲ್ಲಿ, ಡೇಟಾ ಬ್ಲಾಕ್ ಅನ್ನು ಉಳಿದ ನಕಲು ಮಾಡದ ಭಾಗಕ್ಕೆ ಕಡಿಮೆ ಮಾಡಲಾಗುತ್ತದೆ. ಮುಂದಿನ ಬಾರಿ ನೀವು ಕರೆ ಮಾಡಿದಾಗ, ನಕಲು ಮಾಡುವುದು ಈ ಹಂತದಿಂದ ಮುಂದುವರಿಯುತ್ತದೆ.

ಬಫರ್‌ನಲ್ಲಿ ಪ್ರಸ್ತುತ ಲಭ್ಯವಿರುವ ಡೇಟಾದ ಪ್ರಮಾಣವನ್ನು ಓದುವುದು:

int ms_bufferizer_get_avail(MSBufferizer *obj); 

ಕ್ಷೇತ್ರವನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ ಗಾತ್ರ ಬಫರ್.

ಬಫರ್‌ನಲ್ಲಿನ ಡೇಟಾದ ಭಾಗವನ್ನು ತ್ಯಜಿಸುವುದು:

void ms_bufferizer_skip_bytes(MSBufferizer *obj, int bytes);

ಡೇಟಾದ ನಿರ್ದಿಷ್ಟ ಸಂಖ್ಯೆಯ ಬೈಟ್‌ಗಳನ್ನು ಹಿಂಪಡೆಯಲಾಗುತ್ತದೆ ಮತ್ತು ತಿರಸ್ಕರಿಸಲಾಗುತ್ತದೆ. ಹಳೆಯ ಡೇಟಾವನ್ನು ತಿರಸ್ಕರಿಸಲಾಗಿದೆ.

ಬಫರ್‌ನಲ್ಲಿರುವ ಎಲ್ಲಾ ಸಂದೇಶಗಳನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ:

void ms_bufferizer_flush(MSBufferizer *obj); 

ಡೇಟಾ ಕೌಂಟರ್ ಅನ್ನು ಶೂನ್ಯಕ್ಕೆ ಮರುಹೊಂದಿಸಲಾಗಿದೆ.

ಬಫರ್‌ನಲ್ಲಿರುವ ಎಲ್ಲಾ ಸಂದೇಶಗಳನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ:

void ms_bufferizer_uninit(MSBufferizer *obj); 

ಕೌಂಟರ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗಿಲ್ಲ.

ಬಫರ್ ಅನ್ನು ತೆಗೆದುಹಾಕುವುದು ಮತ್ತು ಮೆಮೊರಿಯನ್ನು ಮುಕ್ತಗೊಳಿಸುವುದು:

void ms_bufferizer_destroy(MSBufferizer *obj);  

ಬಫರರ್ ಅನ್ನು ಬಳಸುವ ಉದಾಹರಣೆಗಳನ್ನು ಹಲವಾರು ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮರ್ ಫಿಲ್ಟರ್‌ಗಳ ಮೂಲ ಕೋಡ್‌ನಲ್ಲಿ ಕಾಣಬಹುದು. ಉದಾಹರಣೆಗೆ, MS_L16_ENC ಫಿಲ್ಟರ್‌ನಲ್ಲಿ, ಇದು ಮಾದರಿಗಳಲ್ಲಿನ ಬೈಟ್‌ಗಳನ್ನು ನೆಟ್‌ವರ್ಕ್ ಆರ್ಡರ್‌ನಿಂದ ಹೋಸ್ಟ್ ಆರ್ಡರ್‌ಗೆ ಮರುಹೊಂದಿಸುತ್ತದೆ: l16.c

ಮುಂದಿನ ಲೇಖನದಲ್ಲಿ, ಟಿಕ್ಕರ್ ಲೋಡ್ ಅಂದಾಜಿನ ಸಮಸ್ಯೆಯನ್ನು ನಾವು ನೋಡುತ್ತೇವೆ ಮತ್ತು ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮರ್‌ನಲ್ಲಿ ಅತಿಯಾದ ಕಂಪ್ಯೂಟಿಂಗ್ ಲೋಡ್ ಅನ್ನು ಹೇಗೆ ಎದುರಿಸುವುದು.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ