τα στοιχεία επικοινωνίας μου
Ταχυδρομείο[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Στην προηγούμενη ενότητα "Βασικά στοιχεία για να ξεκινήσετε με ήχο και βίντεο: H.264 θέμα (11) - τύπος για τον υπολογισμό της ανάλυσης βίντεο "", περιγράφει τον τύπο για τον υπολογισμό της ανάλυσης του βίντεο με κωδικοποίηση H.264 μέσω των χαρακτηριστικών στο SPS. Αυτό το άρθρο εξηγεί την εφαρμογή του υπολογισμού της ανάλυσης βίντεο στον πηγαίο κώδικα FFmpeg.
Από το άρθρο "Βασικά στοιχεία για να ξεκινήσετε με ήχο και βίντεο: Θέμα H.264 (10) - Ανάλυση της δομής που αποθηκεύει τα χαρακτηριστικά SPS και η λειτουργία αποκωδικοποίησης SPS στον πηγαίο κώδικα FFmpeg》, μπορούμε να γνωρίζουμε ότι ο πηγαίος κώδικας FFmpeg αποκωδικοποιεί το SPS μέσω της συνάρτησης ff_h264_decode_seq_parameter_set για να πάρει τα χαρακτηριστικά στο SPS.
Υπάρχει ο ακόλουθος κώδικας στη συνάρτηση ff_h264_decode_seq_parameter_set Μέσω του παρακάτω τμήματος του κώδικα, λαμβάνονται τα χαρακτηριστικά που απαιτούνται για τον υπολογισμό της ανάλυσης βίντεο:
- int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
- H264ParamSets *ps, int ignore_truncation)
- {
- //...
-
- sps->gaps_in_frame_num_allowed_flag = get_bits1(gb);
- sps->mb_width = get_ue_golomb(gb) + 1;
- sps->mb_height = get_ue_golomb(gb) + 1;
-
- sps->frame_mbs_only_flag = get_bits1(gb);
-
- if (sps->mb_height >= INT_MAX / 2U) {
- av_log(avctx, AV_LOG_ERROR, "height overflown");
- goto fail;
- }
- sps->mb_height *= 2 - sps->frame_mbs_only_flag;
-
- //...
-
- sps->crop = get_bits1(gb);
- if (sps->crop) {
- unsigned int crop_left = get_ue_golomb(gb);
- unsigned int crop_right = get_ue_golomb(gb);
- unsigned int crop_top = get_ue_golomb(gb);
- unsigned int crop_bottom = get_ue_golomb(gb);
- int width = 16 * sps->mb_width;
- int height = 16 * sps->mb_height;
-
- if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
- av_log(avctx, AV_LOG_DEBUG, "discarding sps cropping, original "
- "values are l:%d r:%d t:%d b:%dn",
- crop_left, crop_right, crop_top, crop_bottom);
-
- sps->crop_left =
- sps->crop_right =
- sps->crop_top =
- sps->crop_bottom = 0;
- } else {
- int vsub = (sps->chroma_format_idc == 1) ? 1 : 0;
- int hsub = (sps->chroma_format_idc == 1 ||
- sps->chroma_format_idc == 2) ? 1 : 0;
- int step_x = 1 << hsub;
- int step_y = (2 - sps->frame_mbs_only_flag) << vsub;
-
- if (crop_left > (unsigned)INT_MAX / 4 / step_x ||
- crop_right > (unsigned)INT_MAX / 4 / step_x ||
- crop_top > (unsigned)INT_MAX / 4 / step_y ||
- crop_bottom> (unsigned)INT_MAX / 4 / step_y ||
- (crop_left + crop_right ) * step_x >= width ||
- (crop_top + crop_bottom) * step_y >= height
- ) {
- av_log(avctx, AV_LOG_ERROR, "crop values invalid %d %d %d %d / %d %dn",
- crop_left, crop_right, crop_top, crop_bottom, width, height);
- goto fail;
- }
-
- sps->crop_left = crop_left * step_x;
- sps->crop_right = crop_right * step_x;
- sps->crop_top = crop_top * step_y;
- sps->crop_bottom = crop_bottom * step_y;
- }
- } else {
- sps->crop_left =
- sps->crop_right =
- sps->crop_top =
- sps->crop_bottom =
- sps->crop = 0;
- }
-
- //...
- }
Στη συνέχεια, στη συνάρτηση parse_nal_units του αρχείου πηγής libavcodec/h264_parser.c του πηγαίου κώδικα FFmpeg, υπάρχει ο ακόλουθος κώδικας:
- static inline int parse_nal_units(AVCodecParserContext *s,
- AVCodecContext *avctx,
- const uint8_t * const buf, int buf_size)
- {
- //...
-
- for (;;) {
- switch (nal.type) {
- case H264_NAL_SPS:
- ff_h264_decode_seq_parameter_set(&nal.gb, avctx, &p->ps, 0);
- break;
-
- //...
-
- case H264_NAL_IDR_SLICE:
-
- //...
-
- s->coded_width = 16 * sps->mb_width;
- s->coded_height = 16 * sps->mb_height;
- s->width = s->coded_width - (sps->crop_right + sps->crop_left);
- s->height = s->coded_height - (sps->crop_top + sps->crop_bottom);
- if (s->width <= 0 || s->height <= 0) {
- s->width = s->coded_width;
- s->height = s->coded_height;
- }
- //...
- }
- //...
- }
- }
Μπορείτε να δείτε ότι στη συνάρτηση parse_nal_units, η ανάλυση του βίντεο λαμβάνεται τελικά μέσω της ακόλουθης πρότασης:
- s->width = s->coded_width - (sps->crop_right + sps->crop_left);
- s->height = s->coded_height - (sps->crop_top + sps->crop_bottom);
Μπορείτε να δείτε την υλοποίηση του υπολογισμού ανάλυσης βίντεο στον πηγαίο κώδικα FFmpeg και στο άρθρο "Βασικά στοιχεία για να ξεκινήσετε με ήχο και βίντεο: H.264 θέμα (11) - τύπος για τον υπολογισμό της ανάλυσης βίντεοΟι τύποι που περιγράφονται στο είναι συνεπείς.