1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

mov: store display matrix in a stream side data

Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
Vittorio Giovara 2014-05-15 22:06:50 -04:00 committed by Anton Khirnov
parent bddd8cbf68
commit 853cc025d6
2 changed files with 53 additions and 9 deletions

View File

@ -135,6 +135,8 @@ typedef struct MOVStreamContext {
int64_t track_end; ///< used for dts generation in fragmented movie files int64_t track_end; ///< used for dts generation in fragmented movie files
unsigned int rap_group_count; unsigned int rap_group_count;
MOVSbgp *rap_group; MOVSbgp *rap_group;
int32_t *display_matrix;
} MOVStreamContext; } MOVStreamContext;
typedef struct MOVContext { typedef struct MOVContext {

View File

@ -2344,7 +2344,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
int width; int width;
int height; int height;
int64_t disp_transform[2]; int64_t disp_transform[2];
int display_matrix[3][2]; int display_matrix[3][3];
AVStream *st; AVStream *st;
MOVStreamContext *sc; MOVStreamContext *sc;
int version; int version;
@ -2381,11 +2381,12 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
//read in the display matrix (outlined in ISO 14496-12, Section 6.2.2) //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
// they're kept in fixed point format through all calculations // they're kept in fixed point format through all calculations
// ignore u,v,z b/c we don't need the scale factor to calc aspect ratio // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
// side data, but the scale factor is not needed to calculate aspect ratio
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
avio_rb32(pb); // 2.30 fixed point (not used) display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
} }
width = avio_rb32(pb); // 16.16 fixed point track width width = avio_rb32(pb); // 16.16 fixed point track width
@ -2393,6 +2394,25 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->width = width >> 16; sc->width = width >> 16;
sc->height = height >> 16; sc->height = height >> 16;
// save the matrix when it is not the default identity
if (display_matrix[0][0] != (1 << 16) ||
display_matrix[1][1] != (1 << 16) ||
display_matrix[2][2] != (1 << 30) ||
display_matrix[0][1] || display_matrix[0][2] ||
display_matrix[1][0] || display_matrix[1][2] ||
display_matrix[2][0] || display_matrix[2][1]) {
int i, j;
av_freep(&sc->display_matrix);
sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
if (!sc->display_matrix)
return AVERROR(ENOMEM);
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
sc->display_matrix[i * 3 + j] = display_matrix[j][i];
}
// transform the display width/height according to the matrix // transform the display width/height according to the matrix
// skip this if the display matrix is the default identity matrix // skip this if the display matrix is the default identity matrix
// or if it is rotating the picture, ex iPhone 3GS // or if it is rotating the picture, ex iPhone 3GS
@ -2975,6 +2995,7 @@ static int mov_read_close(AVFormatContext *s)
av_freep(&sc->stts_data); av_freep(&sc->stts_data);
av_freep(&sc->stps_data); av_freep(&sc->stps_data);
av_freep(&sc->rap_group); av_freep(&sc->rap_group);
av_freep(&sc->display_matrix);
} }
if (mov->dv_demux) { if (mov->dv_demux) {
@ -3049,14 +3070,35 @@ static int mov_read_header(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) { for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i]; AVStream *st = s->streams[i];
MOVStreamContext *sc = st->priv_data;
if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) switch (st->codec->codec_type) {
continue; case AVMEDIA_TYPE_AUDIO:
err = ff_replaygain_export(st, s->metadata);
if (err < 0) {
mov_read_close(s);
return err;
}
break;
case AVMEDIA_TYPE_VIDEO:
if (sc->display_matrix) {
AVPacketSideData *sd, *tmp;
err = ff_replaygain_export(st, s->metadata); tmp = av_realloc_array(st->side_data,
if (err < 0) { st->nb_side_data + 1, sizeof(*tmp));
mov_read_close(s); if (!tmp)
return err; return AVERROR(ENOMEM);
st->side_data = tmp;
st->nb_side_data++;
sd = &st->side_data[st->nb_side_data - 1];
sd->type = AV_PKT_DATA_DISPLAYMATRIX;
sd->size = sizeof(int32_t) * 9;
sd->data = (uint8_t*)sc->display_matrix;
sc->display_matrix = NULL;
}
break;
} }
} }