1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Mpeg video formats-related defines and utility functions 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include <stdint.h> 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "libavutil/common.h" 24cabdff1aSopenharmony_ci#include "libavutil/frame.h" 25cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h" 26cabdff1aSopenharmony_ci#include "libavutil/motion_vector.h" 27cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#include "avcodec.h" 30cabdff1aSopenharmony_ci#include "mpegutils.h" 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_cistatic int add_mb(AVMotionVector *mb, uint32_t mb_type, 33cabdff1aSopenharmony_ci int dst_x, int dst_y, 34cabdff1aSopenharmony_ci int motion_x, int motion_y, int motion_scale, 35cabdff1aSopenharmony_ci int direction) 36cabdff1aSopenharmony_ci{ 37cabdff1aSopenharmony_ci mb->w = IS_8X8(mb_type) || IS_8X16(mb_type) ? 8 : 16; 38cabdff1aSopenharmony_ci mb->h = IS_8X8(mb_type) || IS_16X8(mb_type) ? 8 : 16; 39cabdff1aSopenharmony_ci mb->motion_x = motion_x; 40cabdff1aSopenharmony_ci mb->motion_y = motion_y; 41cabdff1aSopenharmony_ci mb->motion_scale = motion_scale; 42cabdff1aSopenharmony_ci mb->dst_x = dst_x; 43cabdff1aSopenharmony_ci mb->dst_y = dst_y; 44cabdff1aSopenharmony_ci mb->src_x = dst_x + motion_x / motion_scale; 45cabdff1aSopenharmony_ci mb->src_y = dst_y + motion_y / motion_scale; 46cabdff1aSopenharmony_ci mb->source = direction ? 1 : -1; 47cabdff1aSopenharmony_ci mb->flags = 0; // XXX: does mb_type contain extra information that could be exported here? 48cabdff1aSopenharmony_ci return 1; 49cabdff1aSopenharmony_ci} 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_civoid ff_draw_horiz_band(AVCodecContext *avctx, 52cabdff1aSopenharmony_ci AVFrame *cur, AVFrame *last, 53cabdff1aSopenharmony_ci int y, int h, int picture_structure, 54cabdff1aSopenharmony_ci int first_field, int low_delay) 55cabdff1aSopenharmony_ci{ 56cabdff1aSopenharmony_ci const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); 57cabdff1aSopenharmony_ci int vshift = desc->log2_chroma_h; 58cabdff1aSopenharmony_ci const int field_pic = picture_structure != PICT_FRAME; 59cabdff1aSopenharmony_ci if (field_pic) { 60cabdff1aSopenharmony_ci h <<= 1; 61cabdff1aSopenharmony_ci y <<= 1; 62cabdff1aSopenharmony_ci } 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci h = FFMIN(h, avctx->height - y); 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci if (field_pic && first_field && 67cabdff1aSopenharmony_ci !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) 68cabdff1aSopenharmony_ci return; 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci if (avctx->draw_horiz_band) { 71cabdff1aSopenharmony_ci AVFrame *src; 72cabdff1aSopenharmony_ci int offset[AV_NUM_DATA_POINTERS]; 73cabdff1aSopenharmony_ci int i; 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci if (cur->pict_type == AV_PICTURE_TYPE_B || low_delay || 76cabdff1aSopenharmony_ci (avctx->slice_flags & SLICE_FLAG_CODED_ORDER)) 77cabdff1aSopenharmony_ci src = cur; 78cabdff1aSopenharmony_ci else if (last) 79cabdff1aSopenharmony_ci src = last; 80cabdff1aSopenharmony_ci else 81cabdff1aSopenharmony_ci return; 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci if (cur->pict_type == AV_PICTURE_TYPE_B && 84cabdff1aSopenharmony_ci picture_structure == PICT_FRAME && 85cabdff1aSopenharmony_ci avctx->codec_id != AV_CODEC_ID_SVQ3) { 86cabdff1aSopenharmony_ci for (i = 0; i < AV_NUM_DATA_POINTERS; i++) 87cabdff1aSopenharmony_ci offset[i] = 0; 88cabdff1aSopenharmony_ci } else { 89cabdff1aSopenharmony_ci offset[0]= y * src->linesize[0]; 90cabdff1aSopenharmony_ci offset[1]= 91cabdff1aSopenharmony_ci offset[2]= (y >> vshift) * src->linesize[1]; 92cabdff1aSopenharmony_ci for (i = 3; i < AV_NUM_DATA_POINTERS; i++) 93cabdff1aSopenharmony_ci offset[i] = 0; 94cabdff1aSopenharmony_ci } 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_ci emms_c(); 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_ci avctx->draw_horiz_band(avctx, src, offset, 99cabdff1aSopenharmony_ci y, picture_structure, h); 100cabdff1aSopenharmony_ci } 101cabdff1aSopenharmony_ci} 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_civoid ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_table, 104cabdff1aSopenharmony_ci uint32_t *mbtype_table, int8_t *qscale_table, int16_t (*motion_val[2])[2], 105cabdff1aSopenharmony_ci int mb_width, int mb_height, int mb_stride, int quarter_sample) 106cabdff1aSopenharmony_ci{ 107cabdff1aSopenharmony_ci if ((avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS) && mbtype_table && motion_val[0]) { 108cabdff1aSopenharmony_ci const int shift = 1 + quarter_sample; 109cabdff1aSopenharmony_ci const int scale = 1 << shift; 110cabdff1aSopenharmony_ci const int mv_sample_log2 = avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_SVQ3 ? 2 : 1; 111cabdff1aSopenharmony_ci const int mv_stride = (mb_width << mv_sample_log2) + 112cabdff1aSopenharmony_ci (avctx->codec->id == AV_CODEC_ID_H264 ? 0 : 1); 113cabdff1aSopenharmony_ci int mb_x, mb_y, mbcount = 0; 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci /* size is width * height * 2 * 4 where 2 is for directions and 4 is 116cabdff1aSopenharmony_ci * for the maximum number of MB (4 MB in case of IS_8x8) */ 117cabdff1aSopenharmony_ci AVMotionVector *mvs = av_malloc_array(mb_width * mb_height, 2 * 4 * sizeof(AVMotionVector)); 118cabdff1aSopenharmony_ci if (!mvs) 119cabdff1aSopenharmony_ci return; 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci for (mb_y = 0; mb_y < mb_height; mb_y++) { 122cabdff1aSopenharmony_ci for (mb_x = 0; mb_x < mb_width; mb_x++) { 123cabdff1aSopenharmony_ci int i, direction, mb_type = mbtype_table[mb_x + mb_y * mb_stride]; 124cabdff1aSopenharmony_ci for (direction = 0; direction < 2; direction++) { 125cabdff1aSopenharmony_ci if (!USES_LIST(mb_type, direction)) 126cabdff1aSopenharmony_ci continue; 127cabdff1aSopenharmony_ci if (IS_8X8(mb_type)) { 128cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) { 129cabdff1aSopenharmony_ci int sx = mb_x * 16 + 4 + 8 * (i & 1); 130cabdff1aSopenharmony_ci int sy = mb_y * 16 + 4 + 8 * (i >> 1); 131cabdff1aSopenharmony_ci int xy = (mb_x * 2 + (i & 1) + 132cabdff1aSopenharmony_ci (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1); 133cabdff1aSopenharmony_ci int mx = motion_val[direction][xy][0]; 134cabdff1aSopenharmony_ci int my = motion_val[direction][xy][1]; 135cabdff1aSopenharmony_ci mbcount += add_mb(mvs + mbcount, mb_type, sx, sy, mx, my, scale, direction); 136cabdff1aSopenharmony_ci } 137cabdff1aSopenharmony_ci } else if (IS_16X8(mb_type)) { 138cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) { 139cabdff1aSopenharmony_ci int sx = mb_x * 16 + 8; 140cabdff1aSopenharmony_ci int sy = mb_y * 16 + 4 + 8 * i; 141cabdff1aSopenharmony_ci int xy = (mb_x * 2 + (mb_y * 2 + i) * mv_stride) << (mv_sample_log2 - 1); 142cabdff1aSopenharmony_ci int mx = motion_val[direction][xy][0]; 143cabdff1aSopenharmony_ci int my = motion_val[direction][xy][1]; 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_ci if (IS_INTERLACED(mb_type)) 146cabdff1aSopenharmony_ci my *= 2; 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci mbcount += add_mb(mvs + mbcount, mb_type, sx, sy, mx, my, scale, direction); 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci } else if (IS_8X16(mb_type)) { 151cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) { 152cabdff1aSopenharmony_ci int sx = mb_x * 16 + 4 + 8 * i; 153cabdff1aSopenharmony_ci int sy = mb_y * 16 + 8; 154cabdff1aSopenharmony_ci int xy = (mb_x * 2 + i + mb_y * 2 * mv_stride) << (mv_sample_log2 - 1); 155cabdff1aSopenharmony_ci int mx = motion_val[direction][xy][0]; 156cabdff1aSopenharmony_ci int my = motion_val[direction][xy][1]; 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_ci if (IS_INTERLACED(mb_type)) 159cabdff1aSopenharmony_ci my *= 2; 160cabdff1aSopenharmony_ci 161cabdff1aSopenharmony_ci mbcount += add_mb(mvs + mbcount, mb_type, sx, sy, mx, my, scale, direction); 162cabdff1aSopenharmony_ci } 163cabdff1aSopenharmony_ci } else { 164cabdff1aSopenharmony_ci int sx = mb_x * 16 + 8; 165cabdff1aSopenharmony_ci int sy = mb_y * 16 + 8; 166cabdff1aSopenharmony_ci int xy = (mb_x + mb_y * mv_stride) << mv_sample_log2; 167cabdff1aSopenharmony_ci int mx = motion_val[direction][xy][0]; 168cabdff1aSopenharmony_ci int my = motion_val[direction][xy][1]; 169cabdff1aSopenharmony_ci mbcount += add_mb(mvs + mbcount, mb_type, sx, sy, mx, my, scale, direction); 170cabdff1aSopenharmony_ci } 171cabdff1aSopenharmony_ci } 172cabdff1aSopenharmony_ci } 173cabdff1aSopenharmony_ci } 174cabdff1aSopenharmony_ci 175cabdff1aSopenharmony_ci if (mbcount) { 176cabdff1aSopenharmony_ci AVFrameSideData *sd; 177cabdff1aSopenharmony_ci 178cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Adding %d MVs info to frame %d\n", mbcount, avctx->frame_number); 179cabdff1aSopenharmony_ci sd = av_frame_new_side_data(pict, AV_FRAME_DATA_MOTION_VECTORS, mbcount * sizeof(AVMotionVector)); 180cabdff1aSopenharmony_ci if (!sd) { 181cabdff1aSopenharmony_ci av_freep(&mvs); 182cabdff1aSopenharmony_ci return; 183cabdff1aSopenharmony_ci } 184cabdff1aSopenharmony_ci memcpy(sd->data, mvs, mbcount * sizeof(AVMotionVector)); 185cabdff1aSopenharmony_ci } 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci av_freep(&mvs); 188cabdff1aSopenharmony_ci } 189cabdff1aSopenharmony_ci 190cabdff1aSopenharmony_ci /* TODO: export all the following to make them accessible for users (and filters) */ 191cabdff1aSopenharmony_ci if (avctx->hwaccel || !mbtype_table) 192cabdff1aSopenharmony_ci return; 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci if (avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) { 196cabdff1aSopenharmony_ci int x,y; 197cabdff1aSopenharmony_ci 198cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "New frame, type: %c\n", 199cabdff1aSopenharmony_ci av_get_picture_type_char(pict->pict_type)); 200cabdff1aSopenharmony_ci for (y = 0; y < mb_height; y++) { 201cabdff1aSopenharmony_ci for (x = 0; x < mb_width; x++) { 202cabdff1aSopenharmony_ci if (avctx->debug & FF_DEBUG_SKIP) { 203cabdff1aSopenharmony_ci int count = mbskip_table ? mbskip_table[x + y * mb_stride] : 0; 204cabdff1aSopenharmony_ci if (count > 9) 205cabdff1aSopenharmony_ci count = 9; 206cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "%1d", count); 207cabdff1aSopenharmony_ci } 208cabdff1aSopenharmony_ci if (avctx->debug & FF_DEBUG_QP) { 209cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "%2d", 210cabdff1aSopenharmony_ci qscale_table[x + y * mb_stride]); 211cabdff1aSopenharmony_ci } 212cabdff1aSopenharmony_ci if (avctx->debug & FF_DEBUG_MB_TYPE) { 213cabdff1aSopenharmony_ci int mb_type = mbtype_table[x + y * mb_stride]; 214cabdff1aSopenharmony_ci // Type & MV direction 215cabdff1aSopenharmony_ci if (IS_PCM(mb_type)) 216cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "P"); 217cabdff1aSopenharmony_ci else if (IS_INTRA(mb_type) && IS_ACPRED(mb_type)) 218cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "A"); 219cabdff1aSopenharmony_ci else if (IS_INTRA4x4(mb_type)) 220cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "i"); 221cabdff1aSopenharmony_ci else if (IS_INTRA16x16(mb_type)) 222cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "I"); 223cabdff1aSopenharmony_ci else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type)) 224cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "d"); 225cabdff1aSopenharmony_ci else if (IS_DIRECT(mb_type)) 226cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "D"); 227cabdff1aSopenharmony_ci else if (IS_GMC(mb_type) && IS_SKIP(mb_type)) 228cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "g"); 229cabdff1aSopenharmony_ci else if (IS_GMC(mb_type)) 230cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "G"); 231cabdff1aSopenharmony_ci else if (IS_SKIP(mb_type)) 232cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "S"); 233cabdff1aSopenharmony_ci else if (!USES_LIST(mb_type, 1)) 234cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, ">"); 235cabdff1aSopenharmony_ci else if (!USES_LIST(mb_type, 0)) 236cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "<"); 237cabdff1aSopenharmony_ci else { 238cabdff1aSopenharmony_ci av_assert2(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1)); 239cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "X"); 240cabdff1aSopenharmony_ci } 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_ci // segmentation 243cabdff1aSopenharmony_ci if (IS_8X8(mb_type)) 244cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "+"); 245cabdff1aSopenharmony_ci else if (IS_16X8(mb_type)) 246cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "-"); 247cabdff1aSopenharmony_ci else if (IS_8X16(mb_type)) 248cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "|"); 249cabdff1aSopenharmony_ci else if (IS_INTRA(mb_type) || IS_16X16(mb_type)) 250cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, " "); 251cabdff1aSopenharmony_ci else 252cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "?"); 253cabdff1aSopenharmony_ci 254cabdff1aSopenharmony_ci 255cabdff1aSopenharmony_ci if (IS_INTERLACED(mb_type)) 256cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "="); 257cabdff1aSopenharmony_ci else 258cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, " "); 259cabdff1aSopenharmony_ci } 260cabdff1aSopenharmony_ci } 261cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "\n"); 262cabdff1aSopenharmony_ci } 263cabdff1aSopenharmony_ci } 264cabdff1aSopenharmony_ci} 265