2012-02-14 15 views
5

में गति वैक्टर संशोधित करने के लिए शोध उद्देश्यों के लिए, मैं डीकोडिंग प्रक्रिया के दौरान गति मुआवजे से पहले प्रत्येक पी- और बी-फ्रेम के लिए H.264 गति वैक्टर (एमवी) को संशोधित करने का प्रयास कर रहा हूं। मैं इस उद्देश्य के लिए एफएफएमपीईजी का उपयोग कर रहा हूं। एक संशोधन का एक उदाहरण प्रत्येक एमवी को अपने मूल स्थानिक पड़ोसियों के साथ बदल रहा है और फिर मूल के बजाए गति मुआवजे के लिए परिणामस्वरूप एमवी का उपयोग कर रहा है। कृपया मुझे उचित निर्देशित करें।ffmpeg H.264 डीकोडर

अब तक, मैं /libavcodec/h264_cavlc.c फ़ाइल में एमवी का एक सरल संशोधन करने में सक्षम हूं। समारोह, ff_h264_decode_mb_cavlc(), mx और मेरी चर, उदाहरण के लिए संशोधित करते समय, उनके मूल्यों में वृद्धि से डिकोडिंग के दौरान इस्तेमाल किया MVS संशोधित करता है।

उदाहरण के लिए, जैसा कि नीचे दिखाया, mx और मेरी मूल्यों 50 की वृद्धि हुई हैं, इस प्रकार डिकोडर में इस्तेमाल MVS लंबा करते।

mx += get_se_golomb(&s->gb)+50; 
my += get_se_golomb(&s->gb)+50; 

हालांकि, इस संबंध में, मैं कैसे mx और मेरी मेरी स्थानिक के लिए की पड़ोसियों तक पहुँचने के लिए इसका मतलब यह विश्लेषण है कि मैं पहले पैराग्राफ में वर्णित पता नहीं है। मेरा मानना ​​है कि ऐसा करने की कुंजी सरणी में हेरफेर करने में निहित है, mv_cache

मैंने जो अन्य प्रयोग किया वह फ़ाइल में था, libavcodec/error_resilience.cguess_mv() समारोह के आधार पर, मैं एक नया समारोह, mean_mv() कि ff_er_frame_end() पहले अगर-कथन में में निष्पादित किया जाता है बनाया। यह पहला अगर-स्टेटमेंट फ़ंक्शन ff_er_frame_end() से बाहर निकलता है यदि शर्तों में से कोई एक शून्य त्रुटि-गणना (एस-> error_count == 0) है। हालांकि, मैंने इस बिंदु पर अपना mean_mv() फ़ंक्शन डालने का निर्णय लिया ताकि शून्य त्रुटि-गिनती होने पर हमेशा निष्पादित किया जा सके। इस प्रयोग ने कुछ हद तक परिणाम प्राप्त किए जो मैं चाहता था क्योंकि मैं वीडियो के शीर्ष हिस्सों में कलाकृतियों को देखना शुरू कर सकता था लेकिन वे केवल ऊपरी-दाएं कोने तक सीमित थे। मैं अनुमान लगा रहा हूं कि मेरे सम्मिलित फ़ंक्शन को पूरा नहीं किया जा रहा है ताकि प्लेबैक की समयसीमा या कुछ मिल सके।

नीचे संशोधित if-statement है। एकमात्र जोड़ मेरा कार्य है, mean_mv (0)

if(!s->error_recognition || s->error_count==0 || s->avctx->lowres || 
     s->avctx->hwaccel || 
     s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU || 
     s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled 
     s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) { 
     //av_log(s->avctx, AV_LOG_DEBUG, "ff_er_frame_end in er.c\n"); //KG 
     if(s->pict_type==AV_PICTURE_TYPE_P) 
      mean_mv(s); 
     return; 

और यहाँ mean_mv() समारोह मैं guess_mv() आधार पर बनाई गई है।

static void mean_mv(MpegEncContext *s){ 
    //uint8_t fixed[s->mb_stride * s->mb_height]; 
    //const int mb_stride = s->mb_stride; 
    const int mb_width = s->mb_width; 
    const int mb_height= s->mb_height; 
    int mb_x, mb_y, mot_step, mot_stride; 

    //av_log(s->avctx, AV_LOG_DEBUG, "mean_mv\n"); //KG 

    set_mv_strides(s, &mot_step, &mot_stride); 

    for(mb_y=0; mb_y<s->mb_height; mb_y++){ 
     for(mb_x=0; mb_x<s->mb_width; mb_x++){ 
      const int mb_xy= mb_x + mb_y*s->mb_stride; 
      const int mot_index= (mb_x + mb_y*mot_stride) * mot_step; 
      int mv_predictor[4][2]={{0}}; 
      int ref[4]={0}; 
      int pred_count=0; 
      int m, n; 

      if(IS_INTRA(s->current_picture.f.mb_type[mb_xy])) continue; 
      //if(!(s->error_status_table[mb_xy]&MV_ERROR)){ 
      //if (1){ 
      if(mb_x>0){ 
       mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index - mot_step][0]; 
       mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index - mot_step][1]; 
       ref   [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy-1)]; 
       pred_count++; 
      } 

      if(mb_x+1<mb_width){ 
       mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index + mot_step][0]; 
       mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index + mot_step][1]; 
       ref   [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy+1)]; 
       pred_count++; 
      } 

      if(mb_y>0){ 
       mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index - mot_stride*mot_step][0]; 
       mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index - mot_stride*mot_step][1]; 
       ref   [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy-s->mb_stride)]; 
       pred_count++; 
      } 

      if(mb_y+1<mb_height){ 
       mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index + mot_stride*mot_step][0]; 
       mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index + mot_stride*mot_step][1]; 
       ref   [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy+s->mb_stride)]; 
       pred_count++; 
      } 

      if(pred_count==0) continue; 

      if(pred_count>=1){ 
       int sum_x=0, sum_y=0, sum_r=0; 
       int k; 

       for(k=0; k<pred_count; k++){ 
        sum_x+= mv_predictor[k][0]; // Sum all the MVx from MVs avail. for EC 
        sum_y+= mv_predictor[k][1]; // Sum all the MVy from MVs avail. for EC 
        sum_r+= ref[k]; 
        // if(k && ref[k] != ref[k-1]) 
        // goto skip_mean_and_median; 
       } 

       mv_predictor[pred_count][0] = sum_x/k; 
       mv_predictor[pred_count][1] = sum_y/k; 
       ref   [pred_count] = sum_r/k; 
      } 

      s->mv[0][0][0] = mv_predictor[pred_count][0]; 
      s->mv[0][0][1] = mv_predictor[pred_count][1]; 

      for(m=0; m<mot_step; m++){ 
       for(n=0; n<mot_step; n++){ 
        s->current_picture.f.motion_val[0][mot_index + m + n * mot_stride][0] = s->mv[0][0][0]; 
        s->current_picture.f.motion_val[0][mot_index + m + n * mot_stride][1] = s->mv[0][0][1]; 
       } 
      } 

      decode_mb(s, ref[pred_count]); 

      //} 
     } 
    } 
} 

मैं वास्तव में इस बारे में कुछ सहायता के बारे में कुछ सहायता की सराहना करता हूं।

उत्तर

2

यह लंबे समय से हुआ है कि मैं आंतरिक रूप से एफएफएमपीईजी कोड के संपर्क में नहीं रहा हूं।

हालांकि, अंदरूनी एफएफएमपीईजी डरावनी के साथ मेरा अनुभव दिया गया (आपको पता चलेगा कि मेरा क्या मतलब है), मैं आपको एक सरल व्यावहारिक सलाह दूंगा।आप (s a.k.a) FFMPEG एनकोडर संदर्भ के अंदर अपने स्वयं के अतिरिक्त सरणी जो उन सभी को स्टोर करेगा बना सकते हैं -

सुझाव # 1
बेस्ट संभावना है कि जब ब्लॉकों में से प्रत्येक की गति वेक्टर की पहचान कर रहे है। जब आपका एल्गोरिदम चलता है तो वह वहां से मूल्य उठाएगा।

सुझाव # 2
एक और बात मैं पढ़ (मुझे यकीन है कि अगर मैं इसे पढ़ा नहीं कर रहा हूँ सही)

mx और मेरे मान 50

से बढ़ रहे हैं मुझे लगता है कि 50 एक बहुत बड़ा गति वेक्टर है। और आमतौर पर, गति वेक्टर एन्कोडिंग की एफ-वैल्यू रेंज पूर्व प्रतिबंधक होगी। यदि आप +/- 8 (या यहां तक ​​कि +/- 16) द्वारा चीजों को बदलते हैं तो बस ठीक हो सकता है- लेकिन +50 इतना ऊंचा हो सकता है कि अंतिम परिणाम चीजों को सही ढंग से एन्कोड कर सकता है।

मैं काफीmean_mv()और क्या विफलता तुम वहाँ से उम्मीद के बारे में अपने उद्देश्य से नहीं समझा गया था। कृपया थोड़ा सा पुनः वाक्यांश दें।

+0

आपकी टिप्पणी के लिए धन्यवाद। मैं आपके पहले सुझाव में देखूंगा। आपके दूसरे सुझाव के लिए, यह मेरे निष्कर्षों के लिए कुछ हद तक मेल खाता है। जब मैं 'h264_cavlc.c' में गति वेक्टर मान ('mx' और' my') पढ़ता हूं, तो मुझे असाधारण रूप से 500 जैसे बड़े मूल्य मिलते हैं। यह बहुत अनुचित है जब तक कि कुछ स्केलिंग नहीं हो रहा है जैसे कि आपके प्रस्तावित कारक 50 अन्यथा, मुझे नहीं पता कि गति वैक्टर मूल्य क्यों बड़े हैं। – qontranami

+0

'mean_mv() 'के लिए एक पी-फ्रेम पर विचार करें। बी-फ्रेम समर्थन बाद में जोड़ा जाएगा। पी-फ्रेम में गति वैक्टर (एमवी) के साथ मैक्रोब्लॉक शामिल हैं। आइए उन एमवी को 'ए' नामक सेट में समूहित करें। अब, 'mean_mv()' का काम एक नया मोशन वेक्टर सेट, 'बी' का उत्पादन करना है, जो' ए 'को एमवी के अंतिम सेट के रूप में बदल देगा। 'बी' में प्रत्येक एमवी' ए' में संबंधित एमवी का एक संशोधित संस्करण है। 'ए' में एमवी को संशोधित करने का एक तरीका आसपास के एमवी के स्थानिक अर्थ को 'ए' में लेना और परिणाम को 'बी' में रखना है। इस तरह, मैं त्रुटि छिपाने के लिए स्थानिक माध्य और अन्य तकनीकों की प्रभावशीलता की जांच कर सकता हूं। – qontranami

+0

'mean_mv()' वास्तव में एक शानदार विचार है। यह ग्लोबल मोशन वेक्टर (एमपीईजी 4-वी 2 शैली में) अनुमान लगाने में भी मदद कर सकता है। और यह भी कि, आप औसत दृश्य गति को जानते हैं, आप वहां से सभी भविष्यवाणी शुरू कर सकते हैं बल्कि '(0,0)'। शुभकामनाएं 'ffmpeg' खोदना –