2017-07-04 3 views
0

私の携帯電話からポートレートモードで撮影したビデオを持っています。libav autorotate表示マトリックスを無効にする方法

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.MOV': 
Metadata: 
major_brand  : qt 
minor_version : 0 
compatible_brands: qt 
creation_time : 2017-05-04 02:21:37 
Duration: 00:00:06.91, start: 0.000023, bitrate: 4700 kb/s 
Stream #0:0(und): Audio: aac (LC) (mp4a/0x6134706D), 44100 Hz, mono, fltp, 90 kb/s (default) 
Metadata: 
    creation_time : 2017-05-04 02:21:37 
    handler_name : Core Media Data Handler 
Stream #0:1(und): Video: h264 (High) (avc1/0x31637661), yuv420p(tv, bt709), 1280x720, 4602 kb/s, 29.98 fps, 29.97 tbr, 600 tbn, 1200 tbc (default) 
Metadata: 
    rotate   : 90 
    creation_time : 2017-05-04 02:21:37 
    handler_name : Core Media Data Handler 
    encoder   : H.264 
Side data: 
    displaymatrix: rotation of -90.00 degrees 
    5.78 A-V: -0.028 fd= 1 aq= 14KB vq= 351KB sq= 0B f=0/0 

私はビデオをデコード/エンコードするためにlibav apiを使用しています。エンコーディング後、私はビデオの回転バージョンを-90度取得します。

自動回転を防ぐためにデコーダを停止するにはどうすればよいですか?

+0

cliツールの '-noautorotate'オプションに関するソースコードを参照してください。 – LordNeckbeard

+0

@ LordNeckbeard、私はそうしましたが、私はまだlibav apiのautorotaeを無効にすることに問題があります。あなたはそれについての詳細を教えてくれますか? –

答えて

0

表示マトリクス側データによって引き起こされる問題に対処するに長い時間の後、私は次の解決策に出くわした:

は、ビデオストリームと一緒にメタデータとサイドのデータをコピーします。 このコード

AVStream *in_stream; //input stream 
AVStream *out_stream; //output stream 
....   
if(in_stream->side_data!=NULL){ 

    av_log(NULL, AV_LOG_ERROR, "side data size: %d , size: %d\n", in_stream->side_data->size, sizeof(uint8_t*)); 

     if(av_stream_get_side_data(in_stream , AV_PKT_DATA_DISPLAYMATRIX, sd_size)!=NULL){ 

      uint8_t* resp=(uint8_t*) av_mallocz(in_stream->side_data->size+ 
               AV_INPUT_BUFFER_MIN_SIZE); 


      resp = av_stream_get_side_data(in_stream , AV_PKT_DATA_DISPLAYMATRIX, sd_size); 

       av_log(NULL, AV_LOG_DEBUG,"side data detected, size :%d vs %d, " 
             "nb_side_data %d, sizeof data %d," 
             " sizeof resp %d\n", 
        *sd_size, in_stream->side_data->size ,in_stream->nb_side_data, 
        in_stream->side_data->size*sizeof(uint8_t*),sizeof(resp)); 
       in_stream->side_data->data = (uint8_t*) av_mallocz(
          in_stream->side_data->size*sizeof(uint8_t*) 
         ); 
       hasRotation = true; /* it will be used for 
       something like ffmpeg does with noautorotate flag */ 
       av_stream_add_side_data(out_stream, AV_PKT_DATA_DISPLAYMATRIX, resp, *sd_size); 

     } 
    } 

トリックは、得られた映像は、表示マトリクスを持つことになりますんし、いくつかの選手は右それらを表示します。

単純なフィルタの使用 上記のように、ビデオが回転していることを検出できます。私の場合、回転は-90なので、私はフィルターグラフを開始する際にtranspose = clockフィルターを使います。 ffmpeg 3.4.1のトランスコードの例を考えてみましょう。以下のようにコードを変更して、自動回転を-90度にする。

static int init_filters(void) 
{ 
    const char *filter_spec; 
    unsigned int i; 
    int ret; 
    filter_ctx = (FilteringContext*) av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx)); 
if (!filter_ctx) 
    return AVERROR(ENOMEM); 
    for (i = 0; i < ifmt_ctx->nb_streams; i++) { 
     filter_ctx[i].buffersrc_ctx = NULL; 
     filter_ctx[i].buffersink_ctx = NULL; 
     filter_ctx[i].filter_graph = NULL; 
     if (!(ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO 
      || ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)) 
     continue; 
     if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) 
     filter_spec = isRotated ?"transpose=clock":"null"; /* passthrough (dummy) filter for video */ 
    else 
     filter_spec = "anull"; /* passthrough (dummy) filter for audio */ 
    ret = init_filter(&filter_ctx[i], stream_ctx[i].dec_ctx, 
      stream_ctx[i].enc_ctx, filter_spec); 
    if (ret) 
     return ret; 
} 
return 0; 
} 

エンコーダ寸法もスワップされるべきであることに留意されたいです。意味:

enc_ctx->width = dec_ctx->height; 
enc_ctx->height = enc_ctx->width; 

他の人に役立つことを望みます。

関連する問題